Module: Mesa
Branch: master
Commit: e013ce8d0d91f6558af50f285e6a96ab697ec90c
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=e013ce8d0d91f6558af50f285e6a96ab697ec90c

Author: Zhongmin Wu <[email protected]>
Date:   Fri Sep 15 18:32:42 2017 +0100

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]>

---

 src/egl/drivers/dri2/egl_dri2.c             | 72 +++++++++++++++++++++++++++++
 src/egl/drivers/dri2/egl_dri2.h             |  9 ++++
 src/egl/drivers/dri2/platform_android.c     |  3 +-
 src/egl/drivers/dri2/platform_drm.c         |  3 +-
 src/egl/drivers/dri2/platform_surfaceless.c |  3 +-
 src/egl/drivers/dri2/platform_wayland.c     |  3 +-
 src/egl/drivers/dri2/platform_x11.c         |  3 +-
 src/egl/drivers/dri2/platform_x11_dri3.c    |  3 +-
 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 2667aa5d64..42bca61cfd 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 4a52b490a8..10a4151817 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 a864a2af3d..38c1122339 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 0ccbd9a30a..fbdf8b1672 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 1091b4febd..ff8f88d537 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 eb10a7dd13..dc6fcc1d07 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 d80eee2969..ab9a142f41 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 a83e783952..45bb56ca17 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) {

_______________________________________________
mesa-commit mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to