[PATCH 1/9] gles2-renderer: Provide an API for backends to use.

John Kåre Alsaker john.kare.alsaker at gmail.com
Sat Sep 15 11:33:59 PDT 2012


---
 src/compositor-android.c |  72 ++++++++--------------
 src/compositor-drm.c     |  78 ++++++------------------
 src/compositor-wayland.c |  58 ++++--------------
 src/compositor-x11.c     |  71 +++-------------------
 src/compositor.h         |  18 +++++-
 src/gles2-renderer.c     | 151 +++++++++++++++++++++++++++++++++++++++++++----
 6 files changed, 219 insertions(+), 229 deletions(-)

diff --git a/src/compositor-android.c b/src/compositor-android.c
index 3c0273a..753413d 100644
--- a/src/compositor-android.c
+++ b/src/compositor-android.c
@@ -145,6 +145,8 @@ android_output_destroy(struct weston_output *base)
 	wl_list_remove(&output->base.link);
 	weston_output_destroy(&output->base);
 
+	gles2_renderer_output_unbind(base);
+
 	android_framebuffer_destroy(output->fb);
 
 	free(output);
@@ -319,6 +321,8 @@ android_seat_create(struct android_compositor *compositor)
 static int
 android_egl_choose_config(struct android_compositor *compositor,
 			  struct android_framebuffer *fb,
+			  EGLDisplay egl_display,
+			  EGLConfig *egl_config,
 			  const EGLint *attribs)
 {
 	EGLBoolean ret;
@@ -332,9 +336,9 @@ android_egl_choose_config(struct android_compositor *compositor,
 	 * 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;
 
@@ -342,27 +346,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];
+			*egl_config = configs[i];
 			break;
 		}
 	}
 
 out:
 	free(configs);
-	if (!compositor->base.egl_config)
+	if (!*egl_config)
 		return -1;
 
 	return 0;
@@ -372,7 +376,8 @@ static int
 android_init_egl(struct android_compositor *compositor,
 		 struct android_output *output)
 {
-	EGLint eglmajor, eglminor;
+	EGLDisplay egl_display;
+	EGLConfig egl_config;
 	int ret;
 
 	static const EGLint config_attrs[] = {
@@ -385,66 +390,41 @@ android_init_egl(struct android_compositor *compositor,
 		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;
-	}
+	egl_display = gles2_renderer_init_without_config(&compositor->base, EGL_DEFAULT_DISPLAY);
 
-	ret = eglInitialize(compositor->base.egl_display, &eglmajor, &eglminor);
-	if (!ret) {
-		weston_log("Failed to initialise EGL.\n");
+	if (egl_display == EGL_NO_DISPLAY) {
+		weston_log("Failed to create EGL display.\n");
 		print_egl_error_state();
 		return -1;
 	}
 
-	ret = android_egl_choose_config(compositor, output->fb, config_attrs);
+	ret = android_egl_choose_config(compositor, output->fb, egl_display, &egl_config, config_attrs);
 	if (ret < 0) {
 		weston_log("Failed to find an EGL config.\n");
 		print_egl_error_state();
 		return -1;
 	}
 
-	output->base.egl_surface =
-		eglCreateWindowSurface(compositor->base.egl_display,
-				       compositor->base.egl_config,
-				       output->fb->native_window,
-				       NULL);
-	if (output->base.egl_surface == EGL_NO_SURFACE) {
-		weston_log("Failed to create FB EGLSurface.\n");
-		print_egl_error_state();
+	gles2_renderer_select_config(&compositor->base, egl_config);
+
+	if(gles2_renderer_surface_create_and_bind(&output->base, output->fb->native_window) < 0)
 		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);
 }
 
@@ -478,17 +458,17 @@ android_compositor_create(struct wl_display *display, int argc, char *argv[],
 
 	android_compositor_add_output(compositor, output);
 
-	if (gles2_renderer_init(&compositor->base) < 0)
-		goto err_egl;
+	if (gles2_renderer_outputs_ready(&compositor->base) < 0)
+		goto err_gles2;
 
 	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 0faf45c..cba202e 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -862,7 +862,7 @@ drm_output_destroy(struct weston_output *output_base)
 	c->crtc_allocator &= ~(1 << output->crtc_id);
 	c->connector_allocator &= ~(1 << output->connector_id);
 
-	eglDestroySurface(c->base.egl_display, output->base.egl_surface);
+	gles2_renderer_output_unbind(output_base);
 	gbm_surface_destroy(output->surface);
 
 	weston_plane_release(&output->fb_plane);
@@ -968,15 +968,10 @@ drm_output_switch_mode(struct weston_output *output_base, struct weston_mode *mo
 		return -1;
 	}
 
-	egl_surface =
-		eglCreateWindowSurface(ec->base.egl_display,
-				       ec->base.egl_config,
-				       surface, NULL);
+	egl_surface = gles2_renderer_surface_create(&ec->base, surface);
 
-	if (egl_surface == EGL_NO_SURFACE) {
-		weston_log("failed to create egl surface\n");
+	if (egl_surface == EGL_NO_SURFACE)
 		goto err;
-	}
 
 	ret = drmModeSetCrtc(ec->drm.fd,
 			     output->crtc_id,
@@ -1006,10 +1001,10 @@ drm_output_switch_mode(struct weston_output *output_base, struct weston_mode *mo
 	}
 	output->next = NULL;
 
-	eglDestroySurface(ec->base.egl_display, output->base.egl_surface);
+	gles2_renderer_output_unbind(output_base);
 	gbm_surface_destroy(output->surface);
-	output->base.egl_surface = egl_surface;
 	output->surface = surface;
+	gles2_renderer_output_bind(&output->base, egl_surface);
 
 	/*update output*/
 	output->base.current = &drm_mode->base;
@@ -1018,7 +1013,7 @@ drm_output_switch_mode(struct weston_output *output_base, struct weston_mode *mo
 	return 0;
 
 err:
-	eglDestroySurface(ec->base.egl_display, egl_surface);
+	gles2_renderer_surface_destroy(&ec->base, egl_surface);
 	gbm_surface_destroy(surface);
 	return -1;
 }
@@ -1040,18 +1035,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)
@@ -1074,22 +1059,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, 0) < 0)
 		return -1;
-	}
 
 	return 0;
 }
@@ -1446,15 +1418,13 @@ create_output_for_connector(struct drm_compositor *ec,
 		goto err_free;
 	}
 
-	output->base.egl_surface =
-		eglCreateWindowSurface(ec->base.egl_display,
-				       ec->base.egl_config,
-				       output->surface,
-				       NULL);
-	if (output->base.egl_surface == EGL_NO_SURFACE) {
-		weston_log("failed to create egl surface\n");
-		goto err_surface;
-	}
+	weston_output_init(&output->base, &ec->base, x, y,
+			   connector->mmWidth, connector->mmHeight,
+			   o ? o->transform : WL_OUTPUT_TRANSFORM_NORMAL);
+
+	/* this requires output->base.compositor to be initialized */
+	if(gles2_renderer_surface_create_and_bind(&output->base, output->surface) < 0)
+		goto err_output;
 
 	output->cursor_bo[0] =
 		gbm_bo_create(ec->gbm, 64, 64, GBM_FORMAT_ARGB8888,
@@ -1470,10 +1440,6 @@ create_output_for_connector(struct drm_compositor *ec,
 		output->base.backlight_current = drm_get_backlight(output);
 	}
 
-	weston_output_init(&output->base, &ec->base, x, y,
-			   connector->mmWidth, connector->mmHeight,
-			   o ? o->transform : WL_OUTPUT_TRANSFORM_NORMAL);
-
 	wl_list_insert(ec->base.output_list.prev, &output->base.link);
 
 	output->base.origin = output->base.current;
@@ -1500,7 +1466,8 @@ create_output_for_connector(struct drm_compositor *ec,
 
 	return 0;
 
-err_surface:
+err_output:
+	weston_output_destroy(&output->base);
 	gbm_surface_destroy(output->surface);
 err_free:
 	wl_list_for_each_safe(drm_mode, next, &output->base.mode_list,
@@ -2036,12 +2003,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)
@@ -2235,7 +2196,7 @@ drm_compositor_create(struct wl_display *display,
 		goto err_sprite;
 	}
 
-	if (gles2_renderer_init(&ec->base) < 0)
+	if (gles2_renderer_outputs_ready(&ec->base) < 0)
 		goto err_egl;
 
 	path = NULL;
@@ -2277,10 +2238,7 @@ err_drm_source:
 	wl_list_for_each_safe(weston_seat, next, &ec->base.seat_list, link)
 		evdev_input_destroy(weston_seat);
 err_egl:
-	eglMakeCurrent(ec->base.egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
-		       EGL_NO_CONTEXT);
-	eglTerminate(ec->base.egl_display);
-	eglReleaseThread();
+	gles2_renderer_destroy(&ec->base);
 	gbm_device_destroy(ec->gbm);
 err_sprite:
 	destroy_sprites(ec);
diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c
index d665641..fce89a9 100644
--- a/src/compositor-wayland.c
+++ b/src/compositor-wayland.c
@@ -245,41 +245,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)
 {
@@ -323,9 +288,9 @@ static void
 wayland_output_destroy(struct weston_output *output_base)
 {
 	struct wayland_output *output = (struct wayland_output *) output_base;
-	struct weston_compositor *ec = output->base.compositor;
 
-	eglDestroySurface(ec->egl_display, output->base.egl_surface);
+	gles2_renderer_output_unbind(output_base);
+
 	wl_egl_window_destroy(output->parent.egl_window);
 	free(output);
 
@@ -379,13 +344,8 @@ wayland_compositor_create_output(struct wayland_compositor *c,
 		goto cleanup_output;
 	}
 
-	output->base.egl_surface =
-		eglCreateWindowSurface(c->base.egl_display, c->base.egl_config,
-				       output->parent.egl_window, NULL);
-	if (!output->base.egl_surface) {
-		weston_log("failed to create window surface\n");
+	if(gles2_renderer_surface_create_and_bind(&output->base, output->parent.egl_window) < 0)
 		goto cleanup_window;
-	}
 
 	output->parent.shell_surface =
 		wl_shell_get_shell_surface(c->parent.shell,
@@ -837,7 +797,7 @@ wayland_compositor_create(struct wl_display *display,
 	wl_display_iterate(c->parent.wl_display, WL_DISPLAY_READABLE);
 
 	c->base.wl_display = display;
-	if (wayland_compositor_init_egl(c) < 0)
+	if (gles2_renderer_init(&c->base, c->parent.wl_display, 1) < 0)
 		goto err_display;
 
 	c->base.destroy = wayland_destroy;
@@ -845,10 +805,10 @@ wayland_compositor_create(struct wl_display *display,
 
 	create_border(c);
 	if (wayland_compositor_create_output(c, width, height) < 0)
-		goto err_display;
+		goto err_gles2;
 
-	if (gles2_renderer_init(&c->base) < 0)
-		goto err_display;
+	if (gles2_renderer_outputs_ready(&c->base) < 0)
+		goto err_gles2;
 
 	loop = wl_display_get_event_loop(c->base.wl_display);
 
@@ -857,10 +817,12 @@ wayland_compositor_create(struct wl_display *display,
 		wl_event_loop_add_fd(loop, fd, c->parent.event_mask,
 				     wayland_compositor_handle_event, c);
 	if (c->parent.wl_source == NULL)
-		goto err_display;
+		goto err_gles2;
 
 	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 7ec56ff..828c9fd 100644
--- a/src/compositor-x11.c
+++ b/src/compositor-x11.c
@@ -236,53 +236,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)
@@ -319,8 +272,7 @@ x11_output_destroy(struct weston_output *output_base)
 	wl_list_remove(&output->base.link);
 	wl_event_source_remove(output->finish_frame_timer);
 
-	eglDestroySurface(compositor->base.egl_display,
-			  output->base.egl_surface);
+	gles2_renderer_output_unbind(output_base);
 
 	xcb_destroy_window(compositor->conn, output->window);
 
@@ -526,13 +478,8 @@ x11_compositor_create_output(struct x11_compositor *c, int x, int y,
 		x11_output_change_state(output, 1,
 					c->atom.net_wm_state_fullscreen);
 
-	output->base.egl_surface = 
-		eglCreateWindowSurface(c->base.egl_display, c->base.egl_config,
-				       output->window, NULL);
-	if (!output->base.egl_surface) {
-		weston_log("failed to create window surface\n");
+	if(gles2_renderer_surface_create_and_bind(&output->base, output->window) < 0)
 		return NULL;
-	}
 
 	loop = wl_display_get_event_loop(c->base.wl_display);
 	output->finish_frame_timer =
@@ -1080,7 +1027,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);
@@ -1128,14 +1075,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, 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;
@@ -1168,8 +1115,8 @@ x11_compositor_create(struct wl_display *display,
 		x = pixman_region32_extents(&output->base.region)->x2;
 	}
 
-	if (gles2_renderer_init(&c->base) < 0)
-		goto err_egl;
+	if (gles2_renderer_outputs_ready(&c->base) < 0)
+		goto err_x11_input;
 
 	c->xcb_source =
 		wl_event_loop_add_fd(c->base.input_loop,
@@ -1182,8 +1129,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 4760993..873cd9e 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -798,7 +798,23 @@ int
 weston_output_switch_mode(struct weston_output *output, struct weston_mode *mode);
 
 int
-gles2_renderer_init(struct weston_compositor *ec);
+gles2_renderer_init(struct weston_compositor *ec, EGLNativeDisplayType display, int alpha);
+EGLDisplay
+gles2_renderer_init_without_config(struct weston_compositor *ec, EGLNativeDisplayType display);
+void
+gles2_renderer_select_config(struct weston_compositor *ec, EGLConfig config);
+int
+gles2_renderer_outputs_ready(struct weston_compositor *ec);
+int
+gles2_renderer_surface_create_and_bind(struct weston_output *output, EGLNativeWindowType window);
+EGLSurface
+gles2_renderer_surface_create(struct weston_compositor *ec, EGLNativeWindowType window);
+void
+gles2_renderer_surface_destroy(struct weston_compositor *ec, EGLSurface surface);
+void
+gles2_renderer_output_bind(struct weston_output *output, EGLSurface surface);
+void
+gles2_renderer_output_unbind(struct weston_output *output);
 void
 gles2_renderer_destroy(struct weston_compositor *ec);
 
diff --git a/src/gles2-renderer.c b/src/gles2-renderer.c
index 761f4fe..ce5b0ae 100644
--- a/src/gles2-renderer.c
+++ b/src/gles2-renderer.c
@@ -1137,17 +1137,154 @@ struct gles2_renderer {
 	struct weston_renderer base;
 };
 
+static int
+create_renderer(struct weston_compositor *ec)
+{
+	struct gles2_renderer *renderer = malloc(sizeof *renderer);
+
+	if (renderer == NULL)
+		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;
+
+	return 0;
+}
+
+static int
+init_display(struct weston_compositor *ec, EGLNativeDisplayType display)
+{
+	EGLint major, minor;
+
+	if(create_renderer(ec) < 0)
+		return -1;
+
+	ec->egl_display = eglGetDisplay(display);
+	if (ec->egl_display == NULL) {
+		weston_log("failed to create display\n");
+		print_egl_error_state();
+		return -1;
+	}
+
+	if (!eglInitialize(ec->egl_display, &major, &minor)) {
+		weston_log("failed to initialize display\n");
+		print_egl_error_state();
+		return -1;
+	}
+
+	return 0;
+}
+
+WL_EXPORT int
+gles2_renderer_surface_create_and_bind(struct weston_output *output, EGLNativeWindowType window)
+{
+	EGLSurface surface = gles2_renderer_surface_create(output->compositor, window);
+
+	if (surface == EGL_NO_SURFACE)
+		return -1;
+
+	gles2_renderer_output_bind(output, surface);
+
+	return 0;
+}
+
+WL_EXPORT EGLSurface
+gles2_renderer_surface_create(struct weston_compositor *ec, EGLNativeWindowType window)
+{
+	EGLSurface surface =
+		eglCreateWindowSurface(ec->egl_display,
+				       ec->egl_config,
+				       window, NULL);
+
+	if (surface == EGL_NO_SURFACE)
+		weston_log("failed to create egl surface\n");
+
+	return surface;
+}
+
+WL_EXPORT void
+gles2_renderer_surface_destroy(struct weston_compositor *ec, EGLSurface surface)
+{
+	eglDestroySurface(ec->egl_display, surface);
+}
+
+WL_EXPORT void
+gles2_renderer_output_bind(struct weston_output *output, EGLSurface surface)
+{
+	output->egl_surface = surface;
+}
+
+WL_EXPORT void
+gles2_renderer_output_unbind(struct weston_output *output)
+{
+	gles2_renderer_surface_destroy(output->compositor, output->egl_surface);
+}
+
 WL_EXPORT void
 gles2_renderer_destroy(struct weston_compositor *ec)
 {
 	if (ec->has_bind_display)
 		ec->unbind_display(ec->egl_display, ec->wl_display);
+
+	/* Work around crash in egl_dri2.c's dri2_make_current() - when does this apply? */
+	eglMakeCurrent(ec->egl_display,
+		       EGL_NO_SURFACE, EGL_NO_SURFACE,
+		       EGL_NO_CONTEXT);
+
+	eglTerminate(ec->egl_display);
+	eglReleaseThread();
 }
 
 WL_EXPORT int
-gles2_renderer_init(struct weston_compositor *ec)
+gles2_renderer_init(struct weston_compositor *ec, EGLNativeDisplayType display, int alpha)
+{
+	EGLint n;
+
+	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, alpha ? 1 : 0,
+		EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+		EGL_NONE
+	};
+
+	if(init_display(ec, display) < 0)
+		return -1;
+
+	if (!eglChooseConfig(ec->egl_display, config_attribs,
+			     &ec->egl_config, 1, &n) || n != 1) {
+		weston_log("failed to choose config: %d\n", n);
+		print_egl_error_state();
+		return -1;
+	}
+
+	return 0;
+}
+
+WL_EXPORT EGLDisplay
+gles2_renderer_init_without_config(struct weston_compositor *ec, EGLNativeDisplayType display)
+{
+	if(init_display(ec, display) < 0)
+		return EGL_NO_DISPLAY;
+	else
+		return ec->egl_display;
+}
+
+void
+gles2_renderer_select_config(struct weston_compositor *ec, EGLConfig config)
+{
+	ec->egl_config = config;
+}
+
+WL_EXPORT int
+gles2_renderer_outputs_ready(struct weston_compositor *ec)
 {
-	struct gles2_renderer *renderer;
 	const char *extensions;
 	int has_egl_image_external = 0;
 	struct weston_output *output;
@@ -1158,10 +1295,6 @@ gles2_renderer_init(struct weston_compositor *ec)
 		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();
@@ -1259,11 +1392,5 @@ gles2_renderer_init(struct weston_compositor *ec)
 			     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;
-
 	return 0;
 }
-- 
1.7.12



More information about the wayland-devel mailing list