Before we queued the buffer with a invalid fence (-1), it will make some benchmarks failed to test such as flatland.
Now we get the out fence during the flushing buffer and then pass it to SurfaceFlinger in eglSwapbuffer function. v2: a) Also implement the fence in cancelBuffer. b) The last sync fence is stored in drawable object rather than brw context. c) format clear. v3: a) Save the last fence fd in DRI Context object. b) Return the last fence if the batch buffer is empty and nothing to be flushed when _intel_batchbuffer_flush_fence c) Add the new interface in vbtl to set the retrieve fence v3.1 a) close fd in the new vbtl interface on none Android platform v4: a) The last fence is saved in brw context. b) The retrieve fd is for all the platform but not just Android c) Add a uniform dri2 interface to initialize the surface. v4.1: a) make some changes of variable name. b) the patch is breaked into two patches. Change-Id: Ided54d2e193cde73a6f0feb36ac1c0056e4958f2 Signed-off-by: Zhongmin Wu <zhongmin...@intel.com> --- src/egl/drivers/dri2/egl_dri2.c | 45 +++++++++++++++++++++++++++ src/egl/drivers/dri2/egl_dri2.h | 5 +++ src/egl/drivers/dri2/platform_android.c | 11 ++++--- src/egl/drivers/dri2/platform_drm.c | 2 +- src/egl/drivers/dri2/platform_surfaceless.c | 2 +- src/egl/drivers/dri2/platform_wayland.c | 2 +- src/egl/drivers/dri2/platform_x11.c | 2 +- src/egl/drivers/dri2/platform_x11_dri3.c | 2 +- 8 files changed, 62 insertions(+), 9 deletions(-) diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c index 020a0bc..df4e934 100644 --- a/src/egl/drivers/dri2/egl_dri2.c +++ b/src/egl/drivers/dri2/egl_dri2.c @@ -1307,6 +1307,25 @@ dri2_destroy_context(_EGLDriver *drv, _EGLDisplay *disp, _EGLContext *ctx) return EGL_TRUE; } +EGLBoolean +dri2_surf_init(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type, + _EGLConfig *conf, const EGLint *attrib_list) +{ + struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); + dri2_surf->out_fence_fd = -1; + return _eglInitSurface(surf, dpy, type, conf, attrib_list); +} + +static void +dri2_surface_set_retrieve_fence( _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; +} + static EGLBoolean dri2_destroy_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf) { @@ -1315,9 +1334,26 @@ dri2_destroy_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf) if (!_eglPutSurface(surf)) return EGL_TRUE; + dri2_surface_set_retrieve_fence(surf, -1); return dri2_dpy->vtbl->destroy_surface(drv, dpy, surf); } +static void +dri2_surf_get_fence_fd(_EGLContext *ctx, + _EGLDisplay *dpy, _EGLSurface *surf) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy); + int fence_fd = -1; + __DRIcontext *dri_ctx = dri2_egl_context(ctx)->dri_context; + void * 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_retrieve_fence(surf, fence_fd); +} + /** * Called via eglMakeCurrent(), drv->API.MakeCurrent(). */ @@ -1352,8 +1388,11 @@ dri2_make_current(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf, rdraw = (rsurf) ? dri2_dpy->vtbl->get_dri_drawable(rsurf) : NULL; cctx = (dri2_ctx) ? dri2_ctx->dri_context : NULL; + int fence_fd = -1; if (old_ctx) { __DRIcontext *old_cctx = dri2_egl_context(old_ctx)->dri_context; + if (old_dsurf) + dri2_surf_get_fence_fd(old_ctx, disp, old_dsurf); dri2_dpy->core->unbindContext(old_cctx); } @@ -1490,6 +1529,9 @@ 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_get_fence_fd(ctx, dpy, surf); return dri2_dpy->vtbl->swap_buffers(drv, dpy, surf); } @@ -1499,6 +1541,9 @@ 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_get_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 bbba7c0..ca36dd9 100644 --- a/src/egl/drivers/dri2/egl_dri2.h +++ b/src/egl/drivers/dri2/egl_dri2.h @@ -320,6 +320,7 @@ struct dri2_egl_surface __DRIimage *front; unsigned int visual; #endif + int out_fence_fd; }; struct dri2_egl_config @@ -446,4 +447,8 @@ dri2_set_WL_bind_wayland_display(_EGLDriver *drv, _EGLDisplay *disp) void dri2_display_destroy(_EGLDisplay *disp); +EGLBoolean +dri2_surf_init(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type, + _EGLConfig *conf, const EGLint *attrib_list); + #endif /* EGL_DRI2_INCLUDED */ diff --git a/src/egl/drivers/dri2/platform_android.c b/src/egl/drivers/dri2/platform_android.c index cc2e4a6..26ee9fa 100644 --- a/src/egl/drivers/dri2/platform_android.c +++ b/src/egl/drivers/dri2/platform_android.c @@ -305,7 +305,8 @@ droid_window_enqueue_buffer(_EGLDisplay *disp, struct dri2_egl_surface *dri2_sur * is passed to queueBuffer, and the ANativeWindow implementation * is responsible for closing it. */ - int fence_fd = -1; + int fence_fd = dri2_surf->out_fence_fd; + dri2_surf->out_fence_fd = -1; dri2_surf->window->queueBuffer(dri2_surf->window, dri2_surf->buffer, fence_fd); @@ -327,8 +328,10 @@ static void droid_window_cancel_buffer(struct dri2_egl_surface *dri2_surf) { int ret; - - ret = dri2_surf->window->cancelBuffer(dri2_surf->window, dri2_surf->buffer, -1); + int fence_fd = dri2_surf->out_fence_fd; + dri2_surf->out_fence_fd = -1; + ret = dri2_surf->window->cancelBuffer(dri2_surf->window, + dri2_surf->buffer, fence_fd); if (ret < 0) { _eglLog(_EGL_WARNING, "ANativeWindow::cancelBuffer failed"); dri2_surf->base.Lost = EGL_TRUE; @@ -388,7 +391,7 @@ droid_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, return NULL; } - if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list)) + if (!dri2_surf_init(&dri2_surf->base, disp, type, conf, attrib_list)) goto cleanup_surface; if (type == EGL_WINDOW_BIT) { diff --git a/src/egl/drivers/dri2/platform_drm.c b/src/egl/drivers/dri2/platform_drm.c index 8b0562c..52928a8 100644 --- a/src/egl/drivers/dri2/platform_drm.c +++ b/src/egl/drivers/dri2/platform_drm.c @@ -111,7 +111,7 @@ dri2_drm_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, return NULL; } - if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list)) + if (!dri2_surf_init(&dri2_surf->base, disp, type, conf, attrib_list)) goto cleanup_surf; switch (type) { diff --git a/src/egl/drivers/dri2/platform_surfaceless.c b/src/egl/drivers/dri2/platform_surfaceless.c index 0eb3fb7..be6ead0 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_surf_init(&dri2_surf->base, disp, type, conf, attrib_list)) goto cleanup_surface; config = dri2_get_dri_config(dri2_conf, type, diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c index f746f0b..689bbd0 100644 --- a/src/egl/drivers/dri2/platform_wayland.c +++ b/src/egl/drivers/dri2/platform_wayland.c @@ -121,7 +121,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_surf_init(&dri2_surf->base, disp, EGL_WINDOW_BIT, conf, attrib_list)) goto cleanup_surf; if (dri2_dpy->wl_drm) { diff --git a/src/egl/drivers/dri2/platform_x11.c b/src/egl/drivers/dri2/platform_x11.c index 74d3a16..879c40d 100644 --- a/src/egl/drivers/dri2/platform_x11.c +++ b/src/egl/drivers/dri2/platform_x11.c @@ -222,7 +222,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_surf_init(&dri2_surf->base, disp, type, conf, attrib_list)) goto cleanup_surf; dri2_surf->region = XCB_NONE; diff --git a/src/egl/drivers/dri2/platform_x11_dri3.c b/src/egl/drivers/dri2/platform_x11_dri3.c index 3148f49..d92fb39 100644 --- a/src/egl/drivers/dri2/platform_x11_dri3.c +++ b/src/egl/drivers/dri2/platform_x11_dri3.c @@ -183,7 +183,7 @@ dri3_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, return NULL; } - if (!_eglInitSurface(&dri3_surf->base, disp, type, conf, attrib_list)) + if (!dri2_surf_init(&dri3_surf->base, disp, type, conf, attrib_list)) goto cleanup_surf; if (type == EGL_PBUFFER_BIT) { -- 1.7.9.5 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev