---
 src/compositor-android.c | 128 ++++++++++------------------------------
 src/compositor-drm.c     |  38 ++----------
 src/compositor-wayland.c |  46 +++------------
 src/compositor-x11.c     |  57 ++----------------
 src/compositor.h         |   9 ++-
 src/gles2-renderer.c     | 148 +++++++++++++++++++++++++++++++++++------------
 6 files changed, 166 insertions(+), 260 deletions(-)

diff --git a/src/compositor-android.c b/src/compositor-android.c
index 281f093..41933be 100644
--- a/src/compositor-android.c
+++ b/src/compositor-android.c
@@ -78,42 +78,6 @@ to_android_compositor(struct weston_compositor *base)
        return container_of(base, struct android_compositor, base);
 }
 
-static const char *
-egl_error_string(EGLint code)
-{
-#define MYERRCODE(x) case x: return #x;
-       switch (code) {
-       MYERRCODE(EGL_SUCCESS)
-       MYERRCODE(EGL_NOT_INITIALIZED)
-       MYERRCODE(EGL_BAD_ACCESS)
-       MYERRCODE(EGL_BAD_ALLOC)
-       MYERRCODE(EGL_BAD_ATTRIBUTE)
-       MYERRCODE(EGL_BAD_CONTEXT)
-       MYERRCODE(EGL_BAD_CONFIG)
-       MYERRCODE(EGL_BAD_CURRENT_SURFACE)
-       MYERRCODE(EGL_BAD_DISPLAY)
-       MYERRCODE(EGL_BAD_SURFACE)
-       MYERRCODE(EGL_BAD_MATCH)
-       MYERRCODE(EGL_BAD_PARAMETER)
-       MYERRCODE(EGL_BAD_NATIVE_PIXMAP)
-       MYERRCODE(EGL_BAD_NATIVE_WINDOW)
-       MYERRCODE(EGL_CONTEXT_LOST)
-       default:
-               return "unknown";
-       }
-#undef MYERRCODE
-}
-
-static void
-print_egl_error_state(void)
-{
-       EGLint code;
-
-       code = eglGetError();
-       weston_log("EGL error state: %s (0x%04lx)\n",
-               egl_error_string(code), (long)code);
-}
-
 static void
 android_finish_frame(void *data)
 {
@@ -320,24 +284,35 @@ android_seat_create(struct android_compositor *compositor)
 }
 
 static int
-android_egl_choose_config(struct android_compositor *compositor,
-                         struct android_framebuffer *fb,
-                         const EGLint *attribs)
+android_egl_choose_config(void *data,
+                         EGLDisplay egl_display,
+                         EGLConfig *egl_config)
 {
+       static const EGLint 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
+       };
+
        EGLBoolean ret;
        EGLint count = 0;
        EGLint matched = 0;
        EGLConfig *configs;
        int i;
+       struct android_output *output = data;
 
        /*
         * The logic is copied from Android frameworks/base/services/
         * surfaceflinger/DisplayHardware/DisplayHardware.cpp
         */
 
-       compositor->base.egl_config = NULL;
+       *egl_config = NULL;
 
-       ret = eglGetConfigs(compositor->base.egl_display, NULL, 0, &count);
+       ret = eglGetConfigs(egl_display, NULL, 0, &count);
        if (ret == EGL_FALSE || count < 1)
                return -1;
 
@@ -345,27 +320,27 @@ android_egl_choose_config(struct android_compositor 
*compositor,
        if (!configs)
                return -1;
 
-       ret = eglChooseConfig(compositor->base.egl_display, attribs, configs,
+       ret = eglChooseConfig(egl_display, attribs, configs,
                              count, &matched);
        if (ret == EGL_FALSE || matched < 1)
                goto out;
 
        for (i = 0; i < matched; ++i) {
                EGLint id;
-               ret = eglGetConfigAttrib(compositor->base.egl_display,
+               ret = eglGetConfigAttrib(egl_display,
                                         configs[i], EGL_NATIVE_VISUAL_ID,
                                         &id);
                if (ret == EGL_FALSE)
                        continue;
-               if (id > 0 && fb->format == id) {
-                       compositor->base.egl_config = configs[i];
+               if (id > 0 && output->fb->format == id) {
+                       *egl_config = configs[i];
                        break;
                }
        }
 
 out:
        free(configs);
-       if (!compositor->base.egl_config)
+       if (!*egl_config)
                return -1;
 
        return 0;
@@ -375,45 +350,19 @@ static int
 android_init_egl(struct android_compositor *compositor,
                 struct android_output *output)
 {
-       EGLint eglmajor, eglminor;
-       int ret;
        struct gles2_output_state *go;
 
-       static const EGLint config_attrs[] = {
-               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
-       };
-
-       compositor->base.egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-       if (compositor->base.egl_display == EGL_NO_DISPLAY) {
-               weston_log("Failed to create EGL display.\n");
-               print_egl_error_state();
-               return -1;
-       }
-
-       ret = eglInitialize(compositor->base.egl_display, &eglmajor, &eglminor);
-       if (!ret) {
-               weston_log("Failed to initialise EGL.\n");
-               print_egl_error_state();
-               return -1;
-       }
-
-       ret = android_egl_choose_config(compositor, output->fb, config_attrs);
-       if (ret < 0) {
-               weston_log("Failed to find an EGL config.\n");
-               print_egl_error_state();
+       if (gles2_renderer_init(&compositor->base,
+                       EGL_DEFAULT_DISPLAY, android_egl_choose_config,
+                       output) < 0)
                return -1;
-       }
 
        go = gles2_renderer_output_state_create(&compositor->base,
                        output->fb->native_window);
-       if (!go)
+       if (!go) {
+               gles2_renderer_destroy(&compositor->base);
                return -1;
+       }
 
        gles2_renderer_output_bind(&output->base, go);
 
@@ -421,30 +370,17 @@ android_init_egl(struct android_compositor *compositor,
 }
 
 static void
-android_fini_egl(struct android_compositor *compositor)
-{
-       gles2_renderer_destroy(&compositor->base);
-
-       eglMakeCurrent(compositor->base.egl_display,
-                      EGL_NO_SURFACE, EGL_NO_SURFACE,
-                      EGL_NO_CONTEXT);
-
-       eglTerminate(compositor->base.egl_display);
-       eglReleaseThread();
-}
-
-static void
 android_compositor_destroy(struct weston_compositor *base)
 {
        struct android_compositor *compositor = to_android_compositor(base);
 
        android_seat_destroy(compositor->seat);
 
+       gles2_renderer_destroy(base);
+
        /* destroys outputs, too */
        weston_compositor_shutdown(&compositor->base);
 
-       android_fini_egl(compositor);
-
        free(compositor);
 }
 
@@ -480,12 +416,12 @@ android_compositor_create(struct wl_display *display, int 
argc, char *argv[],
 
        compositor->seat = android_seat_create(compositor);
        if (!compositor->seat)
-               goto err_egl;
+               goto err_gles2;
 
        return &compositor->base;
 
-err_egl:
-       android_fini_egl(compositor);
+err_gles2:
+       gles2_renderer_destroy(&compositor->base);
 err_output:
        android_output_destroy(&output->base);
 err_compositor:
diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index 8834f4b..e226b90 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -1039,18 +1039,8 @@ on_drm_input(int fd, uint32_t mask, void *data)
 static int
 init_egl(struct drm_compositor *ec, struct udev_device *device)
 {
-       EGLint major, minor, n;
        const char *filename, *sysnum;
        int fd;
-       static const 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
-       };
 
        sysnum = udev_device_get_sysnum(device);
        if (sysnum)
@@ -1073,20 +1063,9 @@ init_egl(struct drm_compositor *ec, struct udev_device 
*device)
 
        ec->drm.fd = fd;
        ec->gbm = gbm_create_device(ec->drm.fd);
-       ec->base.egl_display = eglGetDisplay(ec->gbm);
-       if (ec->base.egl_display == NULL) {
-               weston_log("failed to create display\n");
-               return -1;
-       }
 
-       if (!eglInitialize(ec->base.egl_display, &major, &minor)) {
-               weston_log("failed to initialize display\n");
-               return -1;
-       }
-
-       if (!eglChooseConfig(ec->base.egl_display, config_attribs,
-                            &ec->base.egl_config, 1, &n) || n != 1) {
-               weston_log("failed to choose config: %d\n", n);
+       if (gles2_renderer_init(&ec->base, ec->gbm, NULL, 0) < 0) {
+               gbm_device_destroy(ec->gbm);
                return -1;
        }
 
@@ -2038,12 +2017,6 @@ drm_destroy(struct weston_compositor *ec)
 
        gles2_renderer_destroy(ec);
 
-       /* Work around crash in egl_dri2.c's dri2_make_current() */
-       eglMakeCurrent(ec->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
-                      EGL_NO_CONTEXT);
-       eglTerminate(ec->egl_display);
-       eglReleaseThread();
-
        gbm_device_destroy(d->gbm);
        destroy_sprites(d);
        if (weston_launcher_drm_set_master(&d->base, d->drm.fd, 0) < 0)
@@ -2310,12 +2283,9 @@ err_drm_source:
        wl_event_source_remove(ec->drm_source);
        wl_list_for_each_safe(weston_seat, next, &ec->base.seat_list, link)
                evdev_input_destroy(weston_seat);
-       eglMakeCurrent(ec->base.egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
-                      EGL_NO_CONTEXT);
-       eglTerminate(ec->base.egl_display);
-       eglReleaseThread();
-       gbm_device_destroy(ec->gbm);
 err_sprite:
+       gles2_renderer_destroy(&ec->base);
+       gbm_device_destroy(ec->gbm);
        destroy_sprites(ec);
 err_udev_dev:
        udev_device_unref(drm_device);
diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c
index 87c1257..8bcf9da 100644
--- a/src/compositor-wayland.c
+++ b/src/compositor-wayland.c
@@ -241,41 +241,6 @@ create_border(struct wayland_compositor *c)
        pixman_image_unref(image);
 }
 
-static int
-wayland_compositor_init_egl(struct wayland_compositor *c)
-{
-       EGLint major, minor;
-       EGLint n;
-       EGLint config_attribs[] = {
-               EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
-               EGL_RED_SIZE, 1,
-               EGL_GREEN_SIZE, 1,
-               EGL_BLUE_SIZE, 1,
-               EGL_ALPHA_SIZE, 1,
-               EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
-               EGL_NONE
-       };
-
-       c->base.egl_display = eglGetDisplay(c->parent.wl_display);
-       if (c->base.egl_display == NULL) {
-               weston_log("failed to create display\n");
-               return -1;
-       }
-
-       if (!eglInitialize(c->base.egl_display, &major, &minor)) {
-               weston_log("failed to initialize display\n");
-               return -1;
-       }
-
-       if (!eglChooseConfig(c->base.egl_display, config_attribs,
-                            &c->base.egl_config, 1, &n) || n == 0) {
-               weston_log("failed to choose config: %d\n", n);
-               return -1;
-       }
-
-       return 0;
-}
-
 static void
 frame_done(void *data, struct wl_callback *callback, uint32_t time)
 {
@@ -832,7 +797,7 @@ wayland_compositor_create(struct wl_display *display,
        wl_display_dispatch(c->parent.wl_display);
 
        c->base.wl_display = display;
-       if (wayland_compositor_init_egl(c) < 0)
+       if (gles2_renderer_init(&c->base, c->parent.wl_display, NULL, (void 
*)1) < 0)
                goto err_display;
 
        c->base.destroy = wayland_destroy;
@@ -845,9 +810,10 @@ wayland_compositor_create(struct wl_display *display,
 
        /* requires border fields */
        if (wayland_compositor_create_output(c, width, height) < 0)
-               goto err_display;
+               goto err_gles2;
 
-       /* requires gles2_renderer_init */
+       /* requires gles2_renderer_output_state_create called
+        * by wayland_compositor_create_output */
        create_border(c);
 
        loop = wl_display_get_event_loop(c->base.wl_display);
@@ -857,12 +823,14 @@ wayland_compositor_create(struct wl_display *display,
                wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE,
                                     wayland_compositor_handle_event, c);
        if (c->parent.wl_source == NULL)
-               goto err_display;
+               goto err_gles2;
 
        wl_event_source_check(c->parent.wl_source);
 
        return &c->base;
 
+err_gles2:
+       gles2_renderer_destroy(&c->base);
 err_display:
        wl_display_disconnect(c->parent.wl_display);
 err_compositor:
diff --git a/src/compositor-x11.c b/src/compositor-x11.c
index 2368869..e0d366c 100644
--- a/src/compositor-x11.c
+++ b/src/compositor-x11.c
@@ -285,53 +285,6 @@ x11_input_destroy(struct x11_compositor *compositor)
        weston_seat_release(&compositor->core_seat);
 }
 
-static int
-x11_compositor_init_egl(struct x11_compositor *c)
-{
-       EGLint major, minor;
-       EGLint n;
-       EGLint config_attribs[] = {
-               EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
-               EGL_RED_SIZE, 1,
-               EGL_GREEN_SIZE, 1,
-               EGL_BLUE_SIZE, 1,
-               EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
-               EGL_NONE
-       };
-
-       c->base.egl_display = eglGetDisplay(c->dpy);
-       if (c->base.egl_display == NULL) {
-               weston_log("failed to create display\n");
-               return -1;
-       }
-
-       if (!eglInitialize(c->base.egl_display, &major, &minor)) {
-               weston_log("failed to initialize display\n");
-               return -1;
-       }
-
-       if (!eglChooseConfig(c->base.egl_display, config_attribs,
-                            &c->base.egl_config, 1, &n) || n == 0) {
-               weston_log("failed to choose config: %d\n", n);
-               return -1;
-       }
-
-       return 0;
-}
-
-static void
-x11_compositor_fini_egl(struct x11_compositor *compositor)
-{
-       gles2_renderer_destroy(&compositor->base);
-
-       eglMakeCurrent(compositor->base.egl_display,
-                      EGL_NO_SURFACE, EGL_NO_SURFACE,
-                      EGL_NO_CONTEXT);
-
-       eglTerminate(compositor->base.egl_display);
-       eglReleaseThread();
-}
-
 static void
 x11_output_repaint(struct weston_output *output_base,
                   pixman_region32_t *damage)
@@ -1104,7 +1057,7 @@ x11_destroy(struct weston_compositor *ec)
 
        weston_compositor_shutdown(ec); /* destroys outputs, too */
 
-       x11_compositor_fini_egl(compositor);
+       gles2_renderer_destroy(ec);
 
        XCloseDisplay(compositor->dpy);
        free(ec);
@@ -1152,14 +1105,14 @@ x11_compositor_create(struct wl_display *display,
        x11_compositor_get_resources(c);
 
        c->base.wl_display = display;
-       if (x11_compositor_init_egl(c) < 0)
+       if (gles2_renderer_init(&c->base, c->dpy, NULL, 0) < 0)
                goto err_xdisplay;
 
        c->base.destroy = x11_destroy;
        c->base.restore = x11_restore;
 
        if (x11_input_create(c, no_input) < 0)
-               goto err_egl;
+               goto err_gles2;
 
        width = option_width ? option_width : 1024;
        height = option_height ? option_height : 640;
@@ -1203,8 +1156,8 @@ x11_compositor_create(struct wl_display *display,
 
 err_x11_input:
        x11_input_destroy(c);
-err_egl:
-       x11_compositor_fini_egl(c);
+err_gles2:
+       gles2_renderer_destroy(&c->base);
 err_xdisplay:
        XCloseDisplay(c->dpy);
 err_free:
diff --git a/src/compositor.h b/src/compositor.h
index 51eabfd..fdd4a58 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -285,9 +285,6 @@ struct weston_renderer {
 struct weston_compositor {
        struct wl_signal destroy_signal;
 
-       EGLDisplay egl_display;
-       EGLContext egl_context;
-       EGLConfig egl_config;
        struct weston_shader texture_shader_rgba;
        struct weston_shader texture_shader_rgbx;
        struct weston_shader texture_shader_egl_external;
@@ -825,6 +822,12 @@ weston_output_switch_mode(struct weston_output *output, 
struct weston_mode *mode
 
 struct gles2_output_state;
 
+typedef int (*gles2_renderer_choose_config_t)(void *data, EGLDisplay display,
+       EGLConfig *config);
+
+int
+gles2_renderer_init(struct weston_compositor *ec, EGLNativeDisplayType display,
+       gles2_renderer_choose_config_t choose_config, void *data);
 struct gles2_output_state *
 gles2_renderer_output_state_create(struct weston_compositor *ec,
                                   EGLNativeWindowType window);
diff --git a/src/gles2-renderer.c b/src/gles2-renderer.c
index f379760..df04f00 100644
--- a/src/gles2-renderer.c
+++ b/src/gles2-renderer.c
@@ -34,6 +34,13 @@ struct gles2_output_state {
        EGLSurface egl_surface;
 };
 
+struct gles2_renderer {
+       struct weston_renderer base;
+
+       EGLDisplay egl_display;
+       EGLContext egl_context;
+       EGLConfig egl_config;
+};
 
 static inline struct gles2_output_state *
 get_output_state(struct weston_output *output)
@@ -41,6 +48,12 @@ get_output_state(struct weston_output *output)
        return (struct gles2_output_state *)output->renderer_state;
 }
 
+static inline struct gles2_renderer *
+get_renderer(struct weston_compositor *ec)
+{
+       return (struct gles2_renderer *)ec->renderer;
+}
+
 static const char *
 egl_error_string(EGLint code)
 {
@@ -713,6 +726,7 @@ gles2_renderer_repaint_output(struct weston_output *output,
 {
        struct gles2_output_state *go = get_output_state(output);
        struct weston_compositor *compositor = output->compositor;
+       struct gles2_renderer *gr = get_renderer(compositor);
        EGLBoolean ret;
        static int errored;
        int32_t width, height, i;
@@ -724,8 +738,8 @@ gles2_renderer_repaint_output(struct weston_output *output,
 
        glViewport(0, 0, width, height);
 
-       ret = eglMakeCurrent(compositor->egl_display, go->egl_surface,
-                            go->egl_surface, compositor->egl_context);
+       ret = eglMakeCurrent(gr->egl_display, go->egl_surface,
+                            go->egl_surface, gr->egl_context);
        if (ret == EGL_FALSE) {
                if (errored)
                        return;
@@ -761,7 +775,7 @@ gles2_renderer_repaint_output(struct weston_output *output,
 
        wl_signal_emit(&output->frame_signal, output);
 
-       ret = eglSwapBuffers(compositor->egl_display, go->egl_surface);
+       ret = eglSwapBuffers(gr->egl_display, go->egl_surface);
        if (ret == EGL_FALSE && !errored) {
                errored = 1;
                weston_log("Failed in eglSwapBuffers.\n");
@@ -833,12 +847,13 @@ static void
 gles2_renderer_attach(struct weston_surface *es, struct wl_buffer *buffer)
 {
        struct weston_compositor *ec = es->compositor;
+       struct gles2_renderer *gr = get_renderer(ec);
        EGLint attribs[3], format;
        int i, num_planes;
 
        if (!buffer) {
                for (i = 0; i < es->num_images; i++) {
-                       ec->destroy_image(ec->egl_display, es->images[i]);
+                       ec->destroy_image(gr->egl_display, es->images[i]);
                        es->images[i] = NULL;
                }
                es->num_images = 0;
@@ -860,10 +875,10 @@ gles2_renderer_attach(struct weston_surface *es, struct 
wl_buffer *buffer)
                        es->shader = &ec->texture_shader_rgbx;
                else
                        es->shader = &ec->texture_shader_rgba;
-       } else if (ec->query_buffer(ec->egl_display, buffer,
+       } else if (ec->query_buffer(gr->egl_display, buffer,
                                    EGL_TEXTURE_FORMAT, &format)) {
                for (i = 0; i < es->num_images; i++)
-                       ec->destroy_image(ec->egl_display, es->images[i]);
+                       ec->destroy_image(gr->egl_display, es->images[i]);
                es->num_images = 0;
                es->target = GL_TEXTURE_2D;
                switch (format) {
@@ -897,7 +912,7 @@ gles2_renderer_attach(struct weston_surface *es, struct 
wl_buffer *buffer)
                        attribs[0] = EGL_WAYLAND_PLANE_WL;
                        attribs[1] = i;
                        attribs[2] = EGL_NONE;
-                       es->images[i] = ec->create_image(ec->egl_display,
+                       es->images[i] = ec->create_image(gr->egl_display,
                                                         NULL,
                                                         EGL_WAYLAND_BUFFER_WL,
                                                         buffer, attribs);
@@ -923,12 +938,13 @@ static void
 gles2_renderer_destroy_surface(struct weston_surface *surface)
 {
        struct weston_compositor *ec = surface->compositor;
+       struct gles2_renderer *gr = get_renderer(ec);
        int i;
 
        glDeleteTextures(surface->num_textures, surface->textures);
 
        for (i = 0; i < surface->num_images; i++)
-               ec->destroy_image(ec->egl_display, surface->images[i]);
+               ec->destroy_image(gr->egl_display, surface->images[i]);
 }
 
 static const char vertex_shader[] =
@@ -1169,10 +1185,6 @@ log_egl_config_info(EGLDisplay egldpy, EGLConfig 
eglconfig)
                weston_log_continue(" unknown\n");
 }
 
-struct gles2_renderer {
-       struct weston_renderer base;
-};
-
 static int
 gles2_renderer_setup(struct weston_compositor *ec, EGLSurface egl_surface);
 
@@ -1180,14 +1192,15 @@ WL_EXPORT struct gles2_output_state *
 gles2_renderer_output_state_create(struct weston_compositor *ec,
                                   EGLNativeWindowType window)
 {
+       struct gles2_renderer *gr = get_renderer(ec);
        struct gles2_output_state *go = calloc(1, sizeof *go);
 
        if (!go)
                return NULL;
 
        go->egl_surface =
-               eglCreateWindowSurface(ec->egl_display,
-                                      ec->egl_config,
+               eglCreateWindowSurface(gr->egl_display,
+                                      gr->egl_config,
                                       window, NULL);
 
        if (go->egl_surface == EGL_NO_SURFACE) {
@@ -1196,7 +1209,7 @@ gles2_renderer_output_state_create(struct 
weston_compositor *ec,
                return NULL;
        }
 
-       if (ec->egl_context == NULL)
+       if (gr->egl_context == NULL)
                if (gles2_renderer_setup(ec, go->egl_surface) < 0) {
                        free(go);
                        return NULL;
@@ -1209,7 +1222,9 @@ WL_EXPORT void
 gles2_renderer_output_state_destroy(struct weston_compositor *ec,
                                    struct gles2_output_state *go)
 {
-       eglDestroySurface(ec->egl_display, go->egl_surface);
+       struct gles2_renderer *gr = get_renderer(ec);
+
+       eglDestroySurface(gr->egl_display, go->egl_surface);
 
        free(go);
 }
@@ -1224,14 +1239,84 @@ gles2_renderer_output_bind(struct weston_output *output,
 WL_EXPORT void
 gles2_renderer_destroy(struct weston_compositor *ec)
 {
+       struct gles2_renderer *gr = get_renderer(ec);
+
        if (ec->has_bind_display)
-               ec->unbind_display(ec->egl_display, ec->wl_display);
+               ec->unbind_display(gr->egl_display, ec->wl_display);
+
+       /* Work around crash in egl_dri2.c's dri2_make_current() - when does 
this apply? */
+       eglMakeCurrent(gr->egl_display,
+                      EGL_NO_SURFACE, EGL_NO_SURFACE,
+                      EGL_NO_CONTEXT);
+
+       eglTerminate(gr->egl_display);
+       eglReleaseThread();
+}
+
+WL_EXPORT int
+gles2_renderer_init(struct weston_compositor *ec, EGLNativeDisplayType display,
+       gles2_renderer_choose_config_t choose_config, void *data)
+{
+       struct gles2_renderer *gr;
+       EGLint major, minor, n;
+       int err;
+
+       const EGLint config_attribs[] = {
+               EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+               EGL_RED_SIZE, 1,
+               EGL_GREEN_SIZE, 1,
+               EGL_BLUE_SIZE, 1,
+               EGL_ALPHA_SIZE, data != 0 ? 1 : 0,
+               EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+               EGL_NONE
+       };
+
+       gr = malloc(sizeof *gr);
+
+       if (gr == NULL)
+               return -1;
+
+       gr->base.repaint_output = gles2_renderer_repaint_output;
+       gr->base.flush_damage = gles2_renderer_flush_damage;
+       gr->base.attach = gles2_renderer_attach;
+       gr->base.destroy_surface = gles2_renderer_destroy_surface;
+
+       gr->egl_display = eglGetDisplay(display);
+       if (gr->egl_display == EGL_NO_DISPLAY) {
+               weston_log("failed to create display\n");
+               goto err_egl;
+       }
+
+       if (!eglInitialize(gr->egl_display, &major, &minor)) {
+               weston_log("failed to initialize display\n");
+               goto err_egl;
+       }
+
+       if (choose_config)
+               err = choose_config(data, gr->egl_display, &gr->egl_config) < 0;
+       else
+               err = !eglChooseConfig(gr->egl_display, config_attribs,
+                                    &gr->egl_config, 1, &n) || n != 1;
+
+       if (err) {
+               weston_log("failed to choose EGL config\n");
+               goto err_egl;
+       }
+
+       ec->renderer = &gr->base;
+
+       return 0;
+
+err_egl:
+       print_egl_error_state();
+       free(gr);
+       return -1;
 }
 
 static int
 gles2_renderer_setup(struct weston_compositor *ec, EGLSurface egl_surface)
 {
-       struct gles2_renderer *renderer;
+       struct gles2_renderer *gr = get_renderer(ec);
        const char *extensions;
        int has_egl_image_external = 0;
        EGLBoolean ret;
@@ -1241,35 +1326,31 @@ gles2_renderer_setup(struct weston_compositor *ec, 
EGLSurface egl_surface)
                EGL_NONE
        };
 
-       renderer = malloc(sizeof *renderer);
-       if (renderer == NULL)
-               return -1;
-
        if (!eglBindAPI(EGL_OPENGL_ES_API)) {
                weston_log("failed to bind EGL_OPENGL_ES_API\n");
                print_egl_error_state();
                return -1;
        }
 
-       log_egl_config_info(ec->egl_display, ec->egl_config);
+       log_egl_config_info(gr->egl_display, gr->egl_config);
 
-       ec->egl_context = eglCreateContext(ec->egl_display, ec->egl_config,
+       gr->egl_context = eglCreateContext(gr->egl_display, gr->egl_config,
                                           EGL_NO_CONTEXT, context_attribs);
-       if (ec->egl_context == NULL) {
+       if (gr->egl_context == NULL) {
                weston_log("failed to create context\n");
                print_egl_error_state();
                return -1;
        }
 
-       ret = eglMakeCurrent(ec->egl_display, egl_surface,
-                            egl_surface, ec->egl_context);
+       ret = eglMakeCurrent(gr->egl_display, egl_surface,
+                            egl_surface, gr->egl_context);
        if (ret == EGL_FALSE) {
                weston_log("Failed to make EGL context current.\n");
                print_egl_error_state();
                return -1;
        }
 
-       log_egl_gl_info(ec->egl_display);
+       log_egl_gl_info(gr->egl_display);
 
        ec->image_target_texture_2d =
                (void *) eglGetProcAddress("glEGLImageTargetTexture2DOES");
@@ -1307,7 +1388,7 @@ gles2_renderer_setup(struct weston_compositor *ec, 
EGLSurface egl_surface)
                has_egl_image_external = 1;
 
        extensions =
-               (const char *) eglQueryString(ec->egl_display, EGL_EXTENSIONS);
+               (const char *) eglQueryString(gr->egl_display, EGL_EXTENSIONS);
        if (!extensions) {
                weston_log("Retrieving EGL extension string failed.\n");
                return -1;
@@ -1316,7 +1397,7 @@ gles2_renderer_setup(struct weston_compositor *ec, 
EGLSurface egl_surface)
        if (strstr(extensions, "EGL_WL_bind_wayland_display"))
                ec->has_bind_display = 1;
        if (ec->has_bind_display) {
-               ret = ec->bind_display(ec->egl_display, ec->wl_display);
+               ret = ec->bind_display(gr->egl_display, ec->wl_display);
                if (!ret)
                        ec->has_bind_display = 0;
        }
@@ -1346,12 +1427,6 @@ gles2_renderer_setup(struct weston_compositor *ec, 
EGLSurface egl_surface)
                             vertex_shader, solid_fragment_shader) < 0)
                return -1;
 
-       renderer->base.repaint_output = gles2_renderer_repaint_output;
-       renderer->base.flush_damage = gles2_renderer_flush_damage;
-       renderer->base.attach = gles2_renderer_attach;
-       renderer->base.destroy_surface = gles2_renderer_destroy_surface;
-       ec->renderer = &renderer->base;
-
        weston_log("GL ES 2 renderer features:\n");
        weston_log_continue(STAMP_SPACE "read-back format: %s\n",
                            ec->read_format == GL_BGRA_EXT ? "BGRA" : "RGBA");
@@ -1360,5 +1435,6 @@ gles2_renderer_setup(struct weston_compositor *ec, 
EGLSurface egl_surface)
        weston_log_continue(STAMP_SPACE "EGL Wayland extension: %s\n",
                            ec->has_bind_display ? "yes" : "no");
 
+
        return 0;
 }
-- 
1.7.12.4

_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to