summaryrefslogtreecommitdiffstats
path: root/src/egl/main/eglapi.c
diff options
context:
space:
mode:
authorPaulo Zanoni <[email protected]>2019-05-01 16:26:47 -0700
committerEric Engestrom <[email protected]>2019-05-14 12:41:14 +0000
commit73055ae1c9f481e439ae2c91bd23652d91b4b42a (patch)
tree1972d2249132923f73c0ce5659b430b2a8863bcc /src/egl/main/eglapi.c
parent04ecda3b3c85b5a3a52f4fa1a3e0f88c17231408 (diff)
egl: check if a window/pixmap is already used on surface creation
The spec says we can't create another surface if we already created a surface with the given window or pixmap. Implement this check. This behavior is exercised by piglit/egl-create-surface. Reviewed-by: Tapani Pälli <[email protected]> Reviewed-by: Eric Engestrom <[email protected]> Signed-off-by: Paulo Zanoni <[email protected]>
Diffstat (limited to 'src/egl/main/eglapi.c')
-rw-r--r--src/egl/main/eglapi.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index 588c6a5f1eb..61a3220705d 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -890,6 +890,32 @@ eglQueryContext(EGLDisplay dpy, EGLContext ctx,
}
+/* In EGL specs 1.4 and 1.5, at the end of sections 3.5.1 and 3.5.4, it says
+ * that if native_surface was already used to create a window or pixmap, we
+ * can't create a new one. This is what this function checks for.
+ */
+static bool
+_eglNativeSurfaceAlreadyUsed(_EGLDisplay *disp, void *native_surface)
+{
+ _EGLResource *list;
+
+ list = disp->ResourceLists[_EGL_RESOURCE_SURFACE];
+ while (list) {
+ _EGLSurface *surf = (_EGLSurface *) list;
+
+ list = list->Next;
+
+ if (surf->Type == EGL_PBUFFER_BIT)
+ continue;
+
+ if (surf->NativeSurface == native_surface)
+ return true;
+ }
+
+ return false;
+}
+
+
static EGLSurface
_eglCreateWindowSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
void *native_window, const EGLint *attrib_list)
@@ -926,6 +952,9 @@ _eglCreateWindowSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
if ((conf->SurfaceType & EGL_WINDOW_BIT) == 0)
RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SURFACE);
+ if (_eglNativeSurfaceAlreadyUsed(disp, native_window))
+ RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);
+
surf = drv->API.CreateWindowSurface(drv, disp, conf, native_window,
attrib_list);
ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
@@ -1051,6 +1080,9 @@ _eglCreatePixmapSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
if (native_pixmap == NULL)
RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE);
+ if (_eglNativeSurfaceAlreadyUsed(disp, native_pixmap))
+ RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);
+
surf = drv->API.CreatePixmapSurface(drv, disp, conf, native_pixmap,
attrib_list);
ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;