From e2392ae6a9bd9ca621d96aac58d3167d66da8fcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tapani=20P=C3=A4lli?= Date: Mon, 19 Dec 2016 11:47:47 +0200 Subject: [PATCH] egl: syncronize surface information with driver RFC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes sure that the values we return are in sync what the driver currently has. Together with dEQP change bug #98327 this fixes following test: dEQP-EGL.functional.resize.surface_size.grow v2: implement callback also for dri3 Signed-off-by: Tapani Pälli Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=98327 --- src/egl/drivers/dri2/egl_dri2.c | 10 ++++++++++ src/egl/drivers/dri2/egl_dri2.h | 2 ++ src/egl/drivers/dri2/platform_x11.c | 29 +++++++++++++++++++++++++++++ src/egl/drivers/dri2/platform_x11_dri3.c | 29 +++++++++++++++++++++++++++++ src/egl/main/eglapi.h | 2 ++ src/egl/main/eglsurface.c | 5 ++++- 6 files changed, 76 insertions(+), 1 deletion(-) diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c index 52fbdff..b7a8afb 100644 --- a/src/egl/drivers/dri2/egl_dri2.c +++ b/src/egl/drivers/dri2/egl_dri2.c @@ -1264,6 +1264,15 @@ dri2_destroy_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf) return dri2_dpy->vtbl->destroy_surface(drv, dpy, surf); } +static EGLBoolean +dri2_sync_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy); + + return dri2_dpy->vtbl->sync_surface(drv, dpy, surf); +} + + /** * Called via eglMakeCurrent(), drv->API.MakeCurrent(). */ @@ -2942,6 +2951,7 @@ _eglBuiltInDriverDRI2(const char *args) dri2_drv->base.API.CreatePixmapSurface = dri2_create_pixmap_surface; dri2_drv->base.API.CreatePbufferSurface = dri2_create_pbuffer_surface; dri2_drv->base.API.DestroySurface = dri2_destroy_surface; + dri2_drv->base.API.SyncSurface = dri2_sync_surface; dri2_drv->base.API.GetProcAddress = dri2_get_proc_address; dri2_drv->base.API.WaitClient = dri2_wait_client; dri2_drv->base.API.WaitNative = dri2_wait_native; diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h index eac58f3..d5cc9b8 100644 --- a/src/egl/drivers/dri2/egl_dri2.h +++ b/src/egl/drivers/dri2/egl_dri2.h @@ -110,6 +110,8 @@ struct dri2_egl_display_vtbl { EGLBoolean (*destroy_surface)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface); + EGLBoolean (*sync_surface)(_EGLDriver *drv, _EGLDisplay *dpy, + _EGLSurface *surface); EGLBoolean (*swap_interval)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint interval); diff --git a/src/egl/drivers/dri2/platform_x11.c b/src/egl/drivers/dri2/platform_x11.c index db7d3b9..979a08c 100644 --- a/src/egl/drivers/dri2/platform_x11.c +++ b/src/egl/drivers/dri2/platform_x11.c @@ -395,6 +395,34 @@ dri2_x11_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf) } /** + * Syncronize surface geometry with server + */ +static EGLBoolean +dri2_x11_sync_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); + xcb_get_geometry_cookie_t cookie; + xcb_get_geometry_reply_t *reply; + xcb_generic_error_t *error; + + cookie = xcb_get_geometry (dri2_dpy->conn, dri2_surf->drawable); + reply = xcb_get_geometry_reply (dri2_dpy->conn, cookie, &error); + if (reply == NULL) + return false; + + if (error != NULL) { + _eglLog(_EGL_WARNING, "error in xcb_get_geometry"); + free(error); + } else { + surf->Width = reply->width; + surf->Height = reply->height; + } + free(reply); + return true; +} + +/** * Process list of buffer received from the server * * Processes the list of buffers received in a reply from the server to either @@ -1124,6 +1152,7 @@ static struct dri2_egl_display_vtbl dri2_x11_display_vtbl = { .create_pixmap_surface = dri2_x11_create_pixmap_surface, .create_pbuffer_surface = dri2_x11_create_pbuffer_surface, .destroy_surface = dri2_x11_destroy_surface, + .sync_surface = dri2_x11_sync_surface, .create_image = dri2_x11_create_image_khr, .swap_interval = dri2_x11_swap_interval, .swap_buffers = dri2_x11_swap_buffers, diff --git a/src/egl/drivers/dri2/platform_x11_dri3.c b/src/egl/drivers/dri2/platform_x11_dri3.c index c474714..dd367bc 100644 --- a/src/egl/drivers/dri2/platform_x11_dri3.c +++ b/src/egl/drivers/dri2/platform_x11_dri3.c @@ -149,6 +149,34 @@ dri3_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf) return EGL_TRUE; } +/** + * Syncronize surface geometry with server + */ +static EGLBoolean +dri3_sync_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); + xcb_get_geometry_cookie_t cookie; + xcb_get_geometry_reply_t *reply; + xcb_generic_error_t *error; + + cookie = xcb_get_geometry (dri2_dpy->conn, dri2_surf->drawable); + reply = xcb_get_geometry_reply (dri2_dpy->conn, cookie, &error); + if (reply == NULL) + return false; + + if (error != NULL) { + _eglLog(_EGL_WARNING, "error in xcb_get_geometry"); + free(error); + } else { + surf->Width = reply->width; + surf->Height = reply->height; + } + free(reply); + return true; +} + static EGLBoolean dri3_set_swap_interval(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf, EGLint interval) @@ -433,6 +461,7 @@ struct dri2_egl_display_vtbl dri3_x11_display_vtbl = { .create_pixmap_surface = dri3_create_pixmap_surface, .create_pbuffer_surface = dri3_create_pbuffer_surface, .destroy_surface = dri3_destroy_surface, + .sync_surface = dri3_sync_surface, .create_image = dri3_create_image_khr, .swap_interval = dri3_set_swap_interval, .swap_buffers = dri3_swap_buffers, diff --git a/src/egl/main/eglapi.h b/src/egl/main/eglapi.h index 710c5d8..5152b93 100644 --- a/src/egl/main/eglapi.h +++ b/src/egl/main/eglapi.h @@ -94,6 +94,8 @@ struct _egl_api const EGLint *attrib_list); EGLBoolean (*DestroySurface)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface); + EGLBoolean (*SyncSurface)(_EGLDriver *drv, _EGLDisplay *dpy, + _EGLSurface *surface); EGLBoolean (*QuerySurface)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, EGLint attribute, EGLint *value); diff --git a/src/egl/main/eglsurface.c b/src/egl/main/eglsurface.c index 04f42ca..aaaec2b 100644 --- a/src/egl/main/eglsurface.c +++ b/src/egl/main/eglsurface.c @@ -333,11 +333,14 @@ _eglInitSurface(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type, return EGL_TRUE; } - EGLBoolean _eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, EGLint attribute, EGLint *value) { + /* Syncronize surface information with the driver. */ + if (drv->API.SyncSurface) + drv->API.SyncSurface(drv, dpy, surface); + switch (attribute) { case EGL_WIDTH: *value = surface->Width; -- 2.9.3