summaryrefslogtreecommitdiffstatsci
path: root/src
diff options
context:
space:
mode:
authorBryce Harrington <b.harrington@samsung.com>2013-11-14 17:17:09 -0800
committerBryce Harrington <b.harrington@samsung.com>2013-11-14 17:17:09 -0800
commit22256defef76a122fb254c993bb9fd9314f4bb6c (patch)
treeb90d00e27ce02a158985c3408b563bd8a395ec39 /src
parent20097d8b646f0f341c02e704b6046e63b7fc608f (diff)
Add egl / gles3 surface support
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/caskbench.cpp13
-rw-r--r--src/surface-egl.cpp131
3 files changed, 142 insertions, 3 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 4b8e0b9..2cfa149 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,6 +1,7 @@
file(GLOB caskbench_SOURCES
caskbench.cpp
surface-glx.cpp
+ surface-egl.cpp
cairo-tests/*.cpp
skia-tests/*.cpp
diff --git a/src/caskbench.cpp b/src/caskbench.cpp
index 29ed6c5..364c07b 100644
--- a/src/caskbench.cpp
+++ b/src/caskbench.cpp
@@ -44,6 +44,8 @@ typedef struct _caskbench_result {
cairo_surface_t *
create_source_surface_glx (int width, int height);
+cairo_surface_t *
+create_source_surface_egl (int width, int height);
void
@@ -143,7 +145,7 @@ process_options(caskbench_options_t *opt, int argc, char *argv[])
"Controls the complexity of the tests, such as number of drawn elements",
NULL},
{"cairo-surface-type", 't', POPT_ARG_STRING, &opt->cairo_surface_type, 0,
- "Type of Cairo surface to use (image, glx)",
+ "Type of Cairo surface to use (image, glx, or egl)",
NULL},
POPT_AUTOHELP
{NULL}
@@ -231,13 +233,18 @@ main (int argc, char *argv[])
context.canvas_width = 800;
context.canvas_height = 400;
- if (opt.cairo_surface_type == NULL || !strcmp(opt.cairo_surface_type, "image"))
+ if (opt.cairo_surface_type == NULL || !strncmp(opt.cairo_surface_type, "image", 5))
cairo_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
context.canvas_width,
context.canvas_height);
- else
+ else if (!strncmp(opt.cairo_surface_type, "glx", 3))
cairo_surface = create_source_surface_glx ( context.canvas_width,
context.canvas_height);
+ else if (!strncmp(opt.cairo_surface_type, "egl", 3))
+ cairo_surface = create_source_surface_egl ( context.canvas_width,
+ context.canvas_height);
+
+
if (!cairo_surface)
errx(2, "Error: Could not create a cairo surface\n");
diff --git a/src/surface-egl.cpp b/src/surface-egl.cpp
new file mode 100644
index 0000000..4676546
--- /dev/null
+++ b/src/surface-egl.cpp
@@ -0,0 +1,131 @@
+#include <err.h>
+#include <stdlib.h>
+#include <cairo.h>
+#include <cairo-gl.h>
+
+#include <EGL/egl.h>
+#include <GLES3/gl3.h>
+
+struct graphics_state {
+ Display *dpy;
+ Window window;
+
+ EGLDisplay egl_display;
+ EGLContext egl_context;
+ EGLSurface egl_surface;
+};
+
+static void
+cleanup (void *data)
+{
+ struct graphics_state *state = (graphics_state*)data;
+
+ eglDestroyContext (state->egl_display, state->egl_context);
+ eglDestroySurface (state->egl_display, state->egl_surface);
+ eglTerminate (state->egl_display);
+
+ XCloseDisplay (state->dpy);
+
+ free (state);
+}
+
+cairo_surface_t *
+create_source_surface_egl (int width, int height)
+{
+ struct graphics_state *state;
+ cairo_device_t *cairo_device;
+ cairo_surface_t *cairo_surface;
+
+ EGLint attr[] = {
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ EGL_RED_SIZE, 1,
+ EGL_GREEN_SIZE, 1,
+ EGL_BLUE_SIZE, 1,
+ EGL_ALPHA_SIZE, 1,
+ EGL_STENCIL_SIZE, 1,
+ EGL_SAMPLES, 4,
+ EGL_SAMPLE_BUFFERS, 1,
+ EGL_NONE
+ };
+ EGLint ctx_attr[] = {
+ EGL_CONTEXT_CLIENT_VERSION, 3,
+ EGL_NONE
+ };
+ EGLConfig config;
+ EGLint num;
+ EGLint major, minor;
+
+ state = (graphics_state*) malloc (sizeof (struct graphics_state));
+ if (!state) {
+ warnx ("Out of memory\n");
+ return NULL;
+ }
+
+ state->dpy = XOpenDisplay (NULL);
+ if (state->dpy == NULL) {
+ warnx ("Failed to open display: %s\n", XDisplayName (0));
+ return NULL;
+ }
+
+ state->window = XCreateSimpleWindow (state->dpy, DefaultRootWindow (state->dpy),
+ 0, 0,
+ width, height,
+ 0,
+ BlackPixel (state->dpy, DefaultRootWindow (state->dpy)),
+ BlackPixel (state->dpy, DefaultRootWindow (state->dpy)));
+ XMapWindow (state->dpy, state->window);
+
+ state->egl_display = eglGetDisplay ((EGLNativeDisplayType) state->dpy);
+ if (state->egl_display == EGL_NO_DISPLAY) {
+ warnx ("Cannot get egl display\n");
+ return NULL;
+ }
+
+ if (! eglInitialize (state->egl_display, &major, &minor)) {
+ warnx ("Cannot initialize egl\n");
+ return NULL;
+ }
+
+ if (! eglBindAPI (EGL_OPENGL_ES_API)) {
+ warnx ("Cannot bind egl to gles2 API\n");
+ return NULL;
+ }
+
+ if (! eglChooseConfig (state->egl_display, attr, &config, 1, &num)) {
+ warnx ("Cannot get egl configuration\n");
+ return NULL;
+ }
+
+ state->egl_context = eglCreateContext (state->egl_display, config, NULL, ctx_attr);
+ if (state->egl_context == EGL_NO_CONTEXT) {
+ warnx ("Cannot create egl context\n");
+ return NULL;
+ }
+
+ state->egl_surface = eglCreateWindowSurface (state->egl_display, config, state->window, NULL);
+ if (state->egl_surface == EGL_NO_SURFACE) {
+ warnx ("Cannot create egl window surface\n");
+ return NULL;
+ }
+
+ cairo_device = cairo_egl_device_create (state->egl_display, state->egl_context);
+ cairo_gl_device_set_thread_aware (cairo_device, 0);
+ cairo_surface = cairo_gl_surface_create_for_egl (cairo_device,
+ state->egl_surface,
+ width, height);
+
+ if (cairo_device_set_user_data (cairo_device,
+ (cairo_user_data_key_t *) cleanup,
+ state,
+ cleanup))
+ {
+ warnx ("Failed to setup cleanup callback closure\n");
+ cleanup (state);
+ return NULL;
+ }
+
+ cairo_device_destroy (cairo_device);
+
+ return cairo_surface;
+}