[PATCH v6 02/12] Move EGLConfig, EGLContext and EGLDisplay fields into gles2-renderer.

John Kåre Alsaker john.kare.alsaker at gmail.com
Tue Nov 13 10:10:19 PST 2012


This moves the EGLConfig, EGLContext and EGLDisplay fields into gles2-renderer. It also moves EGLDisplay creation and EGLConfig selection into gles2-renderer.
---
 src/compositor-android.c | 150 +++--------------------------------
 src/compositor-drm.c     |  39 ++-------
 src/compositor-rpi.c     |  80 ++++---------------
 src/compositor-wayland.c |  48 +++---------
 src/compositor-x11.c     |  58 ++------------
 src/compositor.h         |  11 ++-
 src/gles2-renderer.c     | 200 ++++++++++++++++++++++++++++++++++++++---------
 7 files changed, 221 insertions(+), 365 deletions(-)

diff --git a/src/compositor-android.c b/src/compositor-android.c
index 5bf1df3..cced65d 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)
 {
@@ -319,127 +283,37 @@ android_seat_create(struct android_compositor *compositor)
 }
 
 static int
-android_egl_choose_config(struct android_compositor *compositor,
-			  struct android_framebuffer *fb,
-			  const EGLint *attribs)
-{
-	EGLBoolean ret;
-	EGLint count = 0;
-	EGLint matched = 0;
-	EGLConfig *configs;
-	int i;
-
-	/*
-	 * The logic is copied from Android frameworks/base/services/
-	 * surfaceflinger/DisplayHardware/DisplayHardware.cpp
-	 */
-
-	compositor->base.egl_config = NULL;
-
-	ret = eglGetConfigs(compositor->base.egl_display, NULL, 0, &count);
-	if (ret == EGL_FALSE || count < 1)
-		return -1;
-
-	configs = calloc(count, sizeof *configs);
-	if (!configs)
-		return -1;
-
-	ret = eglChooseConfig(compositor->base.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,
-					 configs[i], EGL_NATIVE_VISUAL_ID,
-					 &id);
-		if (ret == EGL_FALSE)
-			continue;
-		if (id > 0 && fb->format == id) {
-			compositor->base.egl_config = configs[i];
-			break;
-		}
-	}
-
-out:
-	free(configs);
-	if (!compositor->base.egl_config)
-		return -1;
-
-	return 0;
-}
-
-static int
 android_init_egl(struct android_compositor *compositor,
 		 struct android_output *output)
 {
-	EGLint eglmajor, eglminor;
-	int ret;
+	EGLint visual_id = output->fb->format;
 
-	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();
+	if (gles2_renderer_create(&compositor->base,
+			EGL_DEFAULT_DISPLAY, gles2_renderer_opaque_attribs,
+			&visual_id) < 0)
 		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();
-		return -1;
-	}
 
 	if (gles2_renderer_output_create(&output->base,
-			output->fb->native_window) < 0)
+			output->fb->native_window) < 0) {
+		gles2_renderer_destroy(&compositor->base);
 		return -1;
+	}
 
 	return 0;
 }
 
 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);
 }
 
@@ -475,12 +349,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 f7b8d68..42546ff 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -1003,18 +1003,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)
@@ -1037,20 +1027,10 @@ 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_create(&ec->base, ec->gbm, gles2_renderer_opaque_attribs,
+			NULL) < 0) {
+		gbm_device_destroy(ec->gbm);
 		return -1;
 	}
 
@@ -1969,12 +1949,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();
-
 	destroy_sprites(d);
 	gbm_device_destroy(d->gbm);
 	if (weston_launcher_drm_set_master(&d->base, d->drm.fd, 0) < 0)
@@ -2257,12 +2231,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-rpi.c b/src/compositor-rpi.c
index 69f3d59..56119a6 100644
--- a/src/compositor-rpi.c
+++ b/src/compositor-rpi.c
@@ -1089,7 +1089,7 @@ rpi_output_create(struct rpi_compositor *compositor)
 			(EGLNativeWindowType)&output->egl_window) < 0)
 		goto out_output;
 
-	if (!eglSurfaceAttrib(compositor->base.egl_display,
+	if (!eglSurfaceAttrib(gles2_renderer_display(&compositor->base),
 			     gles2_renderer_output_surface(&output->base),
 			      EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED)) {
 		print_egl_error_state();
@@ -1355,63 +1355,6 @@ evdev_input_destroy(struct weston_seat *seat_base)
 	free(seat);
 }
 
-static int
-rpi_init_egl(struct rpi_compositor *compositor)
-{
-	EGLint eglmajor, eglminor;
-	int ret;
-	EGLint num_config;
-
-	static const EGLint config_attrs[] = {
-		EGL_SURFACE_TYPE, EGL_WINDOW_BIT |
-				  EGL_SWAP_BEHAVIOR_PRESERVED_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 = eglChooseConfig(compositor->base.egl_display, config_attrs,
-			      &compositor->base.egl_config, 1, &num_config);
-	if (ret < 0 || num_config != 1) {
-		weston_log("Failed to find an EGL config (found %d configs).\n",
-			   num_config);
-		print_egl_error_state();
-		return -1;
-	}
-
-	return 0;
-}
-
-static void
-rpi_fini_egl(struct rpi_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
 rpi_compositor_destroy(struct weston_compositor *base)
 {
@@ -1424,7 +1367,7 @@ rpi_compositor_destroy(struct weston_compositor *base)
 	/* destroys outputs, too */
 	weston_compositor_shutdown(&compositor->base);
 
-	rpi_fini_egl(compositor);
+	gles2_renderer_destroy(&compositor->base);
 	tty_destroy(compositor->tty);
 
 	bcm_host_deinit();
@@ -1506,6 +1449,16 @@ rpi_compositor_create(struct wl_display *display, int argc, char *argv[],
 	struct rpi_compositor *compositor;
 	const char *seat = default_seat;
 	uint32_t key;
+	static const EGLint config_attrs[] = {
+		EGL_SURFACE_TYPE, EGL_WINDOW_BIT |
+				  EGL_SWAP_BEHAVIOR_PRESERVED_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
+	};
 
 	weston_log("initializing Raspberry Pi backend\n");
 
@@ -1556,18 +1509,19 @@ rpi_compositor_create(struct wl_display *display, int argc, char *argv[],
 	 */
 	bcm_host_init();
 
-	if (rpi_init_egl(compositor) < 0)
+	if (gles2_renderer_create(&compositor->base, EGL_DEFAULT_DISPLAY,
+		config_attrs, NULL) < 0)
 		goto out_tty;
 
 	if (rpi_output_create(compositor) < 0)
-		goto out_egl;
+		goto out_gles2;
 
 	evdev_input_create(&compositor->base, compositor->udev, seat);
 
 	return &compositor->base;
 
-out_egl:
-	rpi_fini_egl(compositor);
+out_gles2:
+	gles2_renderer_destroy(&compositor->base);
 
 out_tty:
 	tty_destroy(compositor->tty);
diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c
index db97713..1645f7d 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)
 {
@@ -827,7 +792,9 @@ 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_create(&c->base, c->parent.wl_display,
+			gles2_renderer_alpha_attribs,
+			NULL) < 0)
 		goto err_display;
 
 	c->base.destroy = wayland_destroy;
@@ -840,9 +807,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);
@@ -852,12 +820,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 cbb2482..145e424 100644
--- a/src/compositor-x11.c
+++ b/src/compositor-x11.c
@@ -307,53 +307,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)
@@ -1153,7 +1106,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);
@@ -1201,14 +1154,15 @@ 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_create(&c->base, c->dpy, gles2_renderer_opaque_attribs,
+			NULL) < 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;
@@ -1252,8 +1206,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 1826594..9d780cd 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -286,9 +286,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;
@@ -838,6 +835,14 @@ weston_surface_destroy(struct weston_surface *surface);
 int
 weston_output_switch_mode(struct weston_output *output, struct weston_mode *mode);
 
+extern const EGLint gles2_renderer_opaque_attribs[];
+extern const EGLint gles2_renderer_alpha_attribs[];
+
+int
+gles2_renderer_create(struct weston_compositor *ec, EGLNativeDisplayType display,
+	const EGLint *attribs, const EGLint *visual_id);
+EGLDisplay
+gles2_renderer_display(struct weston_compositor *ec);
 int
 gles2_renderer_output_create(struct weston_output *output,
 				    EGLNativeWindowType window);
diff --git a/src/gles2-renderer.c b/src/gles2-renderer.c
index 2559602..0f1873d 100644
--- a/src/gles2-renderer.c
+++ b/src/gles2-renderer.c
@@ -31,22 +31,31 @@
 
 #include "compositor.h"
 
+struct gles2_output_state {
+	EGLSurface egl_surface;
+};
+
 struct gles2_renderer {
 	struct weston_renderer base;
 	int fragment_shader_debug;
-};
 
-struct gles2_output_state {
-	EGLSurface egl_surface;
+	EGLDisplay egl_display;
+	EGLContext egl_context;
+	EGLConfig egl_config;
 };
 
-
 static inline struct gles2_output_state *
 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)
 {
@@ -719,6 +728,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;
@@ -730,8 +740,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;
@@ -767,7 +777,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");
@@ -855,12 +865,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;
@@ -882,10 +893,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) {
@@ -919,7 +930,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);
@@ -945,12 +956,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[] =
@@ -1233,14 +1245,15 @@ gles2_renderer_output_create(struct weston_output *output,
 				    EGLNativeWindowType window)
 {
 	struct weston_compositor *ec = output->compositor;
+	struct gles2_renderer *gr = get_renderer(ec);
 	struct gles2_output_state *go = calloc(1, sizeof *go);
 
 	if (!go)
 		return -1;
 
 	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) {
@@ -1249,7 +1262,7 @@ gles2_renderer_output_create(struct weston_output *output,
 		return -1;
 	}
 
-	if (ec->egl_context == NULL)
+	if (gr->egl_context == NULL)
 		if (gles2_renderer_setup(ec, go->egl_surface) < 0) {
 			free(go);
 			return -1;
@@ -1263,9 +1276,10 @@ gles2_renderer_output_create(struct weston_output *output,
 WL_EXPORT void
 gles2_renderer_output_destroy(struct weston_output *output)
 {
+	struct gles2_renderer *gr = get_renderer(output->compositor);
 	struct gles2_output_state *go = get_output_state(output);
 
-	eglDestroySurface(output->compositor->egl_display, go->egl_surface);
+	eglDestroySurface(gr->egl_display, go->egl_surface);
 
 	free(go);
 }
@@ -1279,8 +1293,131 @@ gles2_renderer_output_surface(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();
+}
+
+static int
+egl_choose_config(struct gles2_renderer *gr, const EGLint *attribs,
+	const EGLint *visual_id)
+{
+	EGLint count = 0;
+	EGLint matched = 0;
+	EGLConfig *configs;
+	int i;
+
+	if (!eglGetConfigs(gr->egl_display, NULL, 0, &count) || count < 1)
+		return -1;
+
+	configs = calloc(count, sizeof *configs);
+	if (!configs)
+		return -1;
+
+	if (!eglChooseConfig(gr->egl_display, attribs, configs,
+			      count, &matched))
+		goto out;
+
+	for (i = 0; i < matched; ++i) {
+		EGLint id;
+
+		if (visual_id) {
+			if (!eglGetConfigAttrib(gr->egl_display,
+					configs[i], EGL_NATIVE_VISUAL_ID,
+					&id))
+				continue;
+
+			if (id != *visual_id)
+				continue;
+		}
+
+		gr->egl_config = configs[i];
+
+		free(configs);
+		return 0;
+	}
+
+out:
+	free(configs);
+	return -1;
+}
+
+WL_EXPORT const EGLint gles2_renderer_opaque_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
+};
+
+WL_EXPORT const EGLint gles2_renderer_alpha_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
+};
+
+WL_EXPORT int
+gles2_renderer_create(struct weston_compositor *ec, EGLNativeDisplayType display,
+	const EGLint *attribs, const EGLint *visual_id)
+{
+	struct gles2_renderer *gr;
+	EGLint major, minor;
+
+	gr = calloc(1, 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 (egl_choose_config(gr, attribs, visual_id) < 0) {
+		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;
+}
+
+WL_EXPORT EGLDisplay
+gles2_renderer_display(struct weston_compositor *ec)
+{
+	return get_renderer(ec)->egl_display;
 }
 
 static int
@@ -1340,7 +1477,7 @@ fragment_debug_binding(struct wl_seat *seat, uint32_t time, uint32_t key,
 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;
 	EGLBoolean ret;
 
@@ -1349,35 +1486,31 @@ gles2_renderer_setup(struct weston_compositor *ec, EGLSurface egl_surface)
 		EGL_NONE
 	};
 
-	renderer = calloc(1, 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");
@@ -1415,7 +1548,7 @@ gles2_renderer_setup(struct weston_compositor *ec, EGLSurface egl_surface)
 		ec->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;
@@ -1424,19 +1557,13 @@ 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;
 	}
 
 	glActiveTexture(GL_TEXTURE0);
 
-	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;
-
 	if (compile_shaders(ec))
 		return -1;
 
@@ -1451,5 +1578,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.8.0



More information about the wayland-devel mailing list