[Piglit] [PATCH v2 1/2] egl/utils: Prepare egl_util_run to be called from piglit subtests.

Sarah Sharp sarah.a.sharp at linux.intel.com
Thu Apr 24 16:32:11 PDT 2014


For future EGL tests, I want to be able to use Chad's new piglit EGL
subtest infrastructure, and use the EGL utilities convenience functions
to set up a window, surface, and context.

Currently, egl_util_run calls piglit_report_result() after calling
test.draw.  This means no other subtests get run.  Add a new field in
egl_test to specify whether piglit_report_result() should be called, and
another field to store the result returned from test.draw.

Make sure that egl_util_run() tears down the window, surface, and
context.  Previously it was relying on cleanup being done when the
process died, which won't work if we want to run a second subtest in the
same thread.

TODO:

There's still some work that could be done here to ensure the
initialization steps in egl_util_run aren't done twice (e.g. calling
XOpenDisplay, eglInitialize, etc.)  However, the tests pass in their
current state, so there's no reason they shouldn't be merged.

Thanks a bunch to Chad Versace and Rob Bradford, who helped me debug
this code!

Signed-off-by: Sarah Sharp <sarah.a.sharp at linux.intel.com>
Cc: Chad Versace <chad.versace at linux.intel.com>
Cc: Rob Bradford <rob at linux.intel.com>
---

v2:
 - Remove glFinish in egl_util_run.  Tests still pass without it.
 - Fix memory leak of vinfo in create_window.
 - Make error handling code in egl_util_run more readable/verifiable.
 - Make sure test is const in egl_util_run.

 tests/egl/egl-util.c | 56 +++++++++++++++++++++++++++++++++++-----------------
 tests/egl/egl-util.h |  4 +++-
 2 files changed, 41 insertions(+), 19 deletions(-)

diff --git a/tests/egl/egl-util.c b/tests/egl/egl-util.c
index 226ba0e..a578d85 100644
--- a/tests/egl/egl-util.c
+++ b/tests/egl/egl-util.c
@@ -79,6 +79,8 @@ egl_init_test(struct egl_test *test)
 	test->extensions = no_extensions;
 	test->window_width = egl_default_window_width;
 	test->window_height = egl_default_window_height;
+	test->stop_on_failure = true;
+	test->result = PIGLIT_FAIL;
 }
 
 EGLSurface
@@ -97,7 +99,7 @@ egl_util_create_pixmap(struct egl_state *state,
 	return surf;
 }
 
-static void
+static enum piglit_result
 create_window(struct egl_state *state)
 {
 	XSetWindowAttributes window_attr;
@@ -111,14 +113,14 @@ create_window(struct egl_state *state)
 	if (!eglGetConfigAttrib(state->egl_dpy,
 				state->cfg, EGL_NATIVE_VISUAL_ID, &id)) {
 		fprintf(stderr, "eglGetConfigAttrib() failed\n");
-		piglit_report_result(PIGLIT_FAIL);
+		return PIGLIT_FAIL;
 	}
 
 	template.visualid = id;
 	vinfo = XGetVisualInfo(state->dpy, VisualIDMask, &template, &count);
 	if (count != 1) {
 		fprintf(stderr, "XGetVisualInfo() failed\n");
-		piglit_report_result(PIGLIT_FAIL);
+		return PIGLIT_FAIL;
 	}
 
 	state->depth = vinfo->depth;
@@ -137,6 +139,7 @@ create_window(struct egl_state *state)
 	XMapWindow(state->dpy, state->win);
 
 	XFree(vinfo);
+	return PIGLIT_PASS;
 }
 
 static enum piglit_result
@@ -184,11 +187,10 @@ check_extensions(struct egl_state *state, const struct egl_test *test)
 }
 
 int
-egl_util_run(const struct egl_test *test, int argc, char *argv[])
+egl_util_run(struct egl_test *test, int argc, char *argv[])
 {
 	struct egl_state state;
 	EGLint count;
-	enum piglit_result result;
 	int i, dispatch_api, api_bit = EGL_OPENGL_BIT;
 
 	EGLint ctxAttribsES[] = {
@@ -207,7 +209,8 @@ egl_util_run(const struct egl_test *test, int argc, char *argv[])
 	state.dpy = XOpenDisplay(NULL);
 	if (state.dpy == NULL) {
 		fprintf(stderr, "couldn't open display\n");
-		piglit_report_result(PIGLIT_FAIL);
+		test->result = PIGLIT_FAIL;
+		goto fail;
 	}
 
 	/* read api_bit if EGL_RENDERABLE_TYPE set in the attribs */
@@ -243,12 +246,14 @@ egl_util_run(const struct egl_test *test, int argc, char *argv[])
 	state.egl_dpy = eglGetDisplay(state.dpy);
 	if (state.egl_dpy == EGL_NO_DISPLAY) {
 		fprintf(stderr, "eglGetDisplay() failed\n");
-		piglit_report_result(PIGLIT_FAIL);
+		test->result = PIGLIT_FAIL;
+		goto fail;
 	}
 
 	if (!eglInitialize(state.egl_dpy, &state.major, &state.minor)) {
 		fprintf(stderr, "eglInitialize() failed\n");
-		piglit_report_result(PIGLIT_FAIL);
+		test->result = PIGLIT_FAIL;
+		goto fail;
 	}
 
 	check_extensions(&state, test);
@@ -256,40 +261,55 @@ egl_util_run(const struct egl_test *test, int argc, char *argv[])
 	if (!eglChooseConfig(state.egl_dpy, test->config_attribs, &state.cfg, 1, &count) ||
 	    count == 0) {
 		fprintf(stderr, "eglChooseConfig() failed\n");
-		piglit_report_result(PIGLIT_FAIL);
+		test->result = PIGLIT_FAIL;
+		goto fail;
 	}
 
 	state.ctx = eglCreateContext(state.egl_dpy, state.cfg,
 				     EGL_NO_CONTEXT, ctxAttribs);
 	if (state.ctx == EGL_NO_CONTEXT) {
 		fprintf(stderr, "eglCreateContext() failed\n");
-		piglit_report_result(PIGLIT_FAIL);
+		test->result = PIGLIT_FAIL;
+		goto fail;
 	}
 
 	state.width = test->window_width;
 	state.height = test->window_height;
-	create_window(&state);
+	test->result = create_window(&state);
+	if (test->result != PIGLIT_PASS)
+		goto destroy_ctx;
 
 	state.surf = eglCreateWindowSurface(state.egl_dpy,
 					    state.cfg, state.win, NULL);
 	if (state.surf == EGL_NO_SURFACE) {
 		fprintf(stderr, "eglCreateWindowSurface() failed\n");
-		piglit_report_result(PIGLIT_FAIL);
+		test->result = PIGLIT_FAIL;
+		goto destroy_window;
 	}
 
 	if (!eglMakeCurrent(state.egl_dpy,
 			    state.surf, state.surf, state.ctx)) {
 		fprintf(stderr, "eglMakeCurrent() failed\n");
-		piglit_report_result(PIGLIT_FAIL);
+		test->result = PIGLIT_FAIL;
+		goto destroy_window;
 	}
 
 	piglit_dispatch_default_init(dispatch_api);
 
-	result = event_loop(&state, test);
+	test->result = event_loop(&state, test);
 
+destroy_window:
+	glFinish();
+	eglMakeCurrent(state.egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, state.ctx);
+	XDestroyWindow(state.dpy, state.win);
+destroy_ctx:
+	eglMakeCurrent(state.egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+	eglDestroyContext(state.egl_dpy, state.ctx);
 	eglTerminate(state.egl_dpy);
-
-	piglit_report_result(result);
-
-	return EXIT_SUCCESS;
+fail:
+	if (test->stop_on_failure)
+		piglit_report_result(test->result);
+	if (test->result == PIGLIT_PASS)
+		return EXIT_SUCCESS;
+	return EXIT_FAILURE;
 }
diff --git a/tests/egl/egl-util.h b/tests/egl/egl-util.h
index e1caa94..a2b89d2 100644
--- a/tests/egl/egl-util.h
+++ b/tests/egl/egl-util.h
@@ -35,6 +35,8 @@ struct egl_test {
 	enum piglit_result (*draw)(struct egl_state *state);
 	EGLint window_width;
 	EGLint window_height;
+	bool stop_on_failure;
+	enum piglit_result result;
 };
 
 static const EGLint egl_default_attribs[] = {
@@ -60,7 +62,7 @@ EGLSurface
 egl_util_create_pixmap(struct egl_state *state,
 		       int width, int height, const EGLint *attribs);
 
-int egl_util_run(const struct egl_test *test, int argc, char *argv[]);
+int egl_util_run(struct egl_test *test, int argc, char *argv[]);
 
 int
 egl_probe_front_pixel_rgb(struct egl_state *state,
-- 
1.8.3.2



More information about the Piglit mailing list