diff --git a/configure.ac b/configure.ac
index 86940d5d..8baef885 100644
--- a/configure.ac
+++ b/configure.ac
@@ -65,6 +65,7 @@ AM_CONDITIONAL(ENABLE_EGL, test x$enable_egl = xyes)
if test x$enable_egl = xyes; then
AC_DEFINE([ENABLE_EGL], [1], [Build Weston with EGL support])
PKG_CHECK_MODULES(EGL, [egl >= 7.10 glesv2])
+ PKG_CHECK_MODULES([EGL_TESTS], [egl >= 7.10 glesv2 wayland-client wayland-egl])
fi
AC_ARG_ENABLE(xkbcommon,
diff --git a/protocol/wayland-test.xml b/protocol/wayland-test.xml
index 2993f087..18b66253 100644
--- a/protocol/wayland-test.xml
+++ b/protocol/wayland-test.xml
@@ -51,5 +51,12 @@
+
+
+
+
+
+
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 42788cbf..baf8b7cf 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -17,6 +17,11 @@ weston_tests = \
subsurface.weston \
$(xwayland_test)
+if ENABLE_EGL
+weston_tests += \
+ buffer-count.weston
+endif
+
AM_TESTS_ENVIRONMENT = \
abs_builddir='$(abs_builddir)'; export abs_builddir;
@@ -63,6 +68,10 @@ weston_test_la_SOURCES = \
wayland-test-protocol.c \
wayland-test-server-protocol.h
+if ENABLE_EGL
+weston_test_la_LDFLAGS += $(EGL_TESTS_LIBS)
+endif
+
libtest_runner_la_SOURCES = \
weston-test-runner.c \
weston-test-runner.h
@@ -111,6 +120,9 @@ text_weston_LDADD = libtest-client.la
subsurface_weston_SOURCES = subsurface-test.c
subsurface_weston_LDADD = libtest-client.la
+buffer_count_weston_SOURCES = buffer-count-test.c
+buffer_count_weston_LDADD = libtest-client.la $(EGL_TESTS_LIBS)
+
xwayland_weston_SOURCES = xwayland-test.c
xwayland_weston_CFLAGS = $(GCC_CFLAGS) $(XWAYLAND_TEST_CFLAGS)
xwayland_weston_LDADD = libtest-client.la $(XWAYLAND_TEST_LIBS)
diff --git a/tests/buffer-count-test.c b/tests/buffer-count-test.c
new file mode 100644
index 00000000..ad2bceeb
--- /dev/null
+++ b/tests/buffer-count-test.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright © 2013 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holders not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. The copyright holders make
+ * no representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include
+
+#include "weston-test-client-helper.h"
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+struct test_data {
+ struct client *client;
+
+ EGLDisplay egl_dpy;
+ EGLContext egl_ctx;
+ EGLConfig egl_conf;
+ EGLSurface egl_surface;
+};
+
+static void
+init_egl(struct test_data *test_data)
+{
+ struct wl_egl_window *native_window;
+ struct surface *surface = test_data->client->surface;
+
+ static const EGLint context_attribs[] = {
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL_NONE
+ };
+
+ EGLint config_attribs[] = {
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+ EGL_RED_SIZE, 1,
+ EGL_GREEN_SIZE, 1,
+ EGL_BLUE_SIZE, 1,
+ EGL_ALPHA_SIZE, 0,
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ EGL_NONE
+ };
+
+ EGLint major, minor, n;
+ EGLBoolean ret;
+
+ test_data->egl_dpy = eglGetDisplay((EGLNativeDisplayType)
+ test_data->client->wl_display);
+ assert(test_data->egl_dpy);
+
+ ret = eglInitialize(test_data->egl_dpy, &major, &minor);
+ assert(ret == EGL_TRUE);
+ ret = eglBindAPI(EGL_OPENGL_ES_API);
+ assert(ret == EGL_TRUE);
+
+ ret = eglChooseConfig(test_data->egl_dpy, config_attribs,
+ &test_data->egl_conf, 1, &n);
+ assert(ret && n == 1);
+
+ test_data->egl_ctx = eglCreateContext(test_data->egl_dpy,
+ test_data->egl_conf,
+ EGL_NO_CONTEXT, context_attribs);
+ assert(test_data->egl_ctx);
+
+ native_window =
+ wl_egl_window_create(surface->wl_surface,
+ surface->width,
+ surface->height);
+ test_data->egl_surface =
+ eglCreateWindowSurface(test_data->egl_dpy,
+ test_data->egl_conf,
+ (EGLNativeWindowType) native_window,
+ NULL);
+
+ ret = eglMakeCurrent(test_data->egl_dpy, test_data->egl_surface,
+ test_data->egl_surface, test_data->egl_ctx);
+ assert(ret == EGL_TRUE);
+}
+
+TEST(test_buffer_count)
+{
+ struct test_data test_data;
+ uint32_t buffer_count;
+ int i;
+
+ test_data.client = client_create(10, 10, 10, 10);
+ init_egl(&test_data);
+
+ /* This is meant to represent a typical game loop which is
+ * expecting eglSwapBuffers to block and throttle the
+ * rendering to a sensible frame rate. Therefore it doesn't
+ * expect to have to install a frame callback itself. I'd
+ * imagine this is what a typical SDL game would end up
+ * doing */
+
+ for (i = 0; i < 10; i++) {
+ glClear(GL_COLOR_BUFFER_BIT);
+ eglSwapBuffers(test_data.egl_dpy, test_data.egl_surface);
+ }
+
+ buffer_count = get_n_egl_buffers(test_data.client);
+
+ printf("buffers used = %i\n", buffer_count);
+
+ /* The implementation should only end up creating two buffers
+ * and cycling between them */
+ assert(buffer_count == 2);
+}
diff --git a/tests/weston-test-client-helper.c b/tests/weston-test-client-helper.c
index b19be400..fd265f2e 100644
--- a/tests/weston-test-client-helper.c
+++ b/tests/weston-test-client-helper.c
@@ -111,6 +111,17 @@ move_client(struct client *client, int x, int y)
frame_callback_wait(client, &done);
}
+int
+get_n_egl_buffers(struct client *client)
+{
+ client->test->n_egl_buffers = -1;
+
+ wl_test_get_n_egl_buffers(client->test->wl_test);
+ wl_display_roundtrip(client->wl_display);
+
+ return client->test->n_egl_buffers;
+}
+
static void
pointer_handle_enter(void *data, struct wl_pointer *wl_pointer,
uint32_t serial, struct wl_surface *wl_surface,
@@ -340,8 +351,17 @@ test_handle_pointer_position(void *data, struct wl_test *wl_test,
test->pointer_x, test->pointer_y);
}
+static void
+test_handle_n_egl_buffers(void *data, struct wl_test *wl_test, uint32_t n)
+{
+ struct test *test = data;
+
+ test->n_egl_buffers = n;
+}
+
static const struct wl_test_listener test_listener = {
- test_handle_pointer_position
+ test_handle_pointer_position,
+ test_handle_n_egl_buffers,
};
static void
diff --git a/tests/weston-test-client-helper.h b/tests/weston-test-client-helper.h
index a5edca90..c78fc28b 100644
--- a/tests/weston-test-client-helper.h
+++ b/tests/weston-test-client-helper.h
@@ -51,6 +51,7 @@ struct test {
struct wl_test *wl_test;
int pointer_x;
int pointer_y;
+ uint32_t n_egl_buffers;
};
struct input {
@@ -120,4 +121,7 @@ frame_callback_set(struct wl_surface *surface, int *done);
void
frame_callback_wait(struct client *client, int *done);
+int
+get_n_egl_buffers(struct client *client);
+
#endif
diff --git a/tests/weston-test.c b/tests/weston-test.c
index fc025fa6..844059dc 100644
--- a/tests/weston-test.c
+++ b/tests/weston-test.c
@@ -20,6 +20,8 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include "config.h"
+
#include
#include
#include
@@ -28,6 +30,11 @@
#include "../src/compositor.h"
#include "wayland-test-server-protocol.h"
+#ifdef ENABLE_EGL
+#include
+#include
+#endif /* ENABLE_EGL */
+
struct weston_test {
struct weston_compositor *compositor;
struct weston_layer layer;
@@ -181,12 +188,54 @@ send_key(struct wl_client *client, struct wl_resource *resource,
notify_key(seat, 100, key, state, STATE_UPDATE_AUTOMATIC);
}
+#ifdef ENABLE_EGL
+static int
+is_egl_buffer(struct wl_resource *resource)
+{
+ PFNEGLQUERYWAYLANDBUFFERWL query_buffer =
+ (void *) eglGetProcAddress("eglQueryWaylandBufferWL");
+ EGLint format;
+
+ if (query_buffer(eglGetCurrentDisplay(),
+ resource,
+ EGL_TEXTURE_FORMAT,
+ &format))
+ return 1;
+
+ return 0;
+}
+#endif /* ENABLE_EGL */
+
+static void
+get_n_buffers(struct wl_client *client, struct wl_resource *resource)
+{
+ int n_buffers = 0;
+
+#ifdef ENABLE_EGL
+ struct wl_resource *buffer_resource;
+ int i;
+
+ for (i = 0; i < 1000; i++) {
+ buffer_resource = wl_client_get_object(client, i);
+
+ if (buffer_resource == NULL)
+ continue;
+
+ if (is_egl_buffer(buffer_resource))
+ n_buffers++;
+ }
+#endif /* ENABLE_EGL */
+
+ wl_test_send_n_egl_buffers(resource, n_buffers);
+}
+
static const struct wl_test_interface test_implementation = {
move_surface,
move_pointer,
send_button,
activate_surface,
- send_key
+ send_key,
+ get_n_buffers,
};
static void