summaryrefslogtreecommitdiffstats
path: root/src/egl/main/eglapi.c
diff options
context:
space:
mode:
authorChad Versace <[email protected]>2017-05-04 17:46:33 -0700
committerChad Versace <[email protected]>2017-05-04 17:46:33 -0700
commit23c86c74cc450a23848b85cfe914376caede1cdf (patch)
treed6c13a8d1a82849afcad93409ae9140a14d76297 /src/egl/main/eglapi.c
parent69e6eab6533ff48f72223cd21ef640242c52598b (diff)
egl: Emit error when EGLSurface is lost
Add a new bool, _EGLSurface::Lost, and check it in eglMakeCurrent and eglSwapBuffers. The EGL 1.5 spec says that those functions emit errors when the native surface is no longer valid. This patch just updates core EGL. No driver sets _EGLSurface::Lost yet. I discovered that Mesa failed to detect lost surfaces while debugging an Android CTS camera test, android.hardware.camera2.cts.RobustnessTest#testAbandonRepeatingRequestSurface. This patch doesn't fix the test though, though, because the test expects EGL_BAD_SURFACE when the surface becomes lost, and this patch actually complies with the EGL spec. If I interpreted the EGL spec correctly, EGL_BAD_NATIVE_WINDOW or EGL_BAD_CURRENT_SURFACE is the correct error. Cc: [email protected] Cc: Tomasz Figa <[email protected]> Cc: Tapani Pälli <[email protected]> Reviewed-by: Nicolas Boichat <[email protected]> Reviewed-by: Emil Velikov <[email protected]>
Diffstat (limited to 'src/egl/main/eglapi.c')
-rw-r--r--src/egl/main/eglapi.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index fc243a58e8c..a459b9ffcdf 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -828,6 +828,33 @@ eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
}
+ _EGLThreadInfo *t =_eglGetCurrentThread();
+ _EGLContext *old_ctx = t->CurrentContext;
+ _EGLSurface *old_draw_surf = old_ctx ? old_ctx->DrawSurface : NULL;
+ _EGLSurface *old_read_surf = old_ctx ? old_ctx->ReadSurface : NULL;
+
+ /* From the EGL 1.5 spec, Section 3.7.3 Binding Context and Drawables:
+ *
+ * If the previous context of the calling thread has unflushed commands,
+ * and the previous surface is no longer valid, an
+ * EGL_BAD_CURRENT_SURFACE error is generated.
+ *
+ * It's difficult to check if the context has unflushed commands, but it's
+ * easy to check if the surface is no longer valid.
+ */
+ if (old_draw_surf && old_draw_surf->Lost)
+ RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
+ if (old_read_surf && old_read_surf->Lost)
+ RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
+
+ /* If a native window underlying either draw or read is no longer valid,
+ * an EGL_BAD_NATIVE_WINDOW error is generated.
+ */
+ if (draw_surf && draw_surf->Lost)
+ RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_FALSE);
+ if (read_surf && read_surf->Lost)
+ RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_FALSE);
+
ret = drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context);
RETURN_EGL_EVAL(disp, ret);
@@ -1215,6 +1242,15 @@ eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
#endif
+ /* From the EGL 1.5 spec:
+ *
+ * If eglSwapBuffers is called and the native window associated with
+ * surface is no longer valid, an EGL_BAD_NATIVE_WINDOW error is
+ * generated.
+ */
+ if (surf->Lost)
+ RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_FALSE);
+
ret = drv->API.SwapBuffers(drv, disp, surf);
RETURN_EGL_EVAL(disp, ret);