[PATCH v5 01/11] Move weston_output EGL state into gles2-renderer.

John Kåre Alsaker john.kare.alsaker at gmail.com
Fri Nov 9 12:21:10 PST 2012


---
 src/compositor-android.c | 21 ++++++------
 src/compositor-drm.c     | 52 ++++++++++++++----------------
 src/compositor-rpi.c     | 43 ++++++++++---------------
 src/compositor-wayland.c | 21 ++++++------
 src/compositor-x11.c     | 18 ++++-------
 src/compositor.h         | 18 +++++++++--
 src/gles2-renderer.c     | 83 ++++++++++++++++++++++++++++++++++++++++++------
 7 files changed, 152 insertions(+), 104 deletions(-)

diff --git a/src/compositor-android.c b/src/compositor-android.c
index 3c0273a..281f093 100644
--- a/src/compositor-android.c
+++ b/src/compositor-android.c
@@ -145,6 +145,9 @@ android_output_destroy(struct weston_output *base)
 	wl_list_remove(&output->base.link);
 	weston_output_destroy(&output->base);
 
+	gles2_renderer_output_state_destroy(base->compositor,
+					    base->renderer_state);
+
 	android_framebuffer_destroy(output->fb);
 
 	free(output);
@@ -374,6 +377,7 @@ android_init_egl(struct android_compositor *compositor,
 {
 	EGLint eglmajor, eglminor;
 	int ret;
+	struct gles2_output_state *go;
 
 	static const EGLint config_attrs[] = {
 		EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
@@ -406,16 +410,12 @@ android_init_egl(struct android_compositor *compositor,
 		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();
+	go = gles2_renderer_output_state_create(&compositor->base,
+			output->fb->native_window);
+	if (!go)
 		return -1;
-	}
+
+	gles2_renderer_output_bind(&output->base, go);
 
 	return 0;
 }
@@ -478,9 +478,6 @@ 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;
-
 	compositor->seat = android_seat_create(compositor);
 	if (!compositor->seat)
 		goto err_egl;
diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index 5fe234d..ae8f906 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -829,7 +829,9 @@ 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_state_destroy(output_base->compositor,
+					    output_base->renderer_state);
+
 	gbm_surface_destroy(output->surface);
 
 	weston_plane_release(&output->fb_plane);
@@ -875,7 +877,7 @@ drm_output_switch_mode(struct weston_output *output_base, struct weston_mode *mo
 	int ret;
 	struct drm_compositor *ec;
 	struct gbm_surface *surface;
-	EGLSurface egl_surface;
+	struct gles2_output_state *go;
 
 	if (output_base == NULL) {
 		weston_log("output is NULL.\n");
@@ -935,15 +937,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);
+	go = gles2_renderer_output_state_create(&ec->base, surface);
 
-	if (egl_surface == EGL_NO_SURFACE) {
-		weston_log("failed to create egl surface\n");
-		goto err;
-	}
+	if (!go)
+		goto err_gbm;
 
 	ret = drmModeSetCrtc(ec->drm.fd,
 			     output->crtc_id,
@@ -951,7 +948,7 @@ drm_output_switch_mode(struct weston_output *output_base, struct weston_mode *mo
 			     &output->connector_id, 1, &drm_mode->mode_info);
 	if (ret) {
 		weston_log("failed to set mode\n");
-		goto err;
+		goto err_gles2;
 	}
 
 	/* reset rendering stuff. */
@@ -973,10 +970,12 @@ 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_state_destroy(output_base->compositor,
+					    output_base->renderer_state);
+
 	gbm_surface_destroy(output->surface);
-	output->base.egl_surface = egl_surface;
 	output->surface = surface;
+	gles2_renderer_output_bind(&output->base, go);
 
 	/*update output*/
 	output->base.current = &drm_mode->base;
@@ -984,8 +983,9 @@ drm_output_switch_mode(struct weston_output *output_base, struct weston_mode *mo
 	weston_output_move(&output->base, output->base.x, output->base.y);
 	return 0;
 
-err:
-	eglDestroySurface(ec->base.egl_display, egl_surface);
+err_gles2:
+	gles2_renderer_output_state_destroy(&ec->base, go);
+err_gbm:
 	gbm_surface_destroy(surface);
 	return -1;
 }
@@ -1259,6 +1259,7 @@ create_output_for_connector(struct drm_compositor *ec,
 	int i;
 	char name[32];
 	const char *type_name;
+	struct gles2_output_state *go;
 
 	i = find_crtc_for_connector(ec, resources, connector);
 	if (i < 0) {
@@ -1387,15 +1388,9 @@ 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;
-	}
+	go = gles2_renderer_output_state_create(&ec->base, output->surface);
+	if (!go)
+		goto err_output;
 
 	output->cursor_bo[0] =
 		gbm_bo_create(ec->gbm, 64, 64, GBM_FORMAT_ARGB8888,
@@ -1421,6 +1416,8 @@ create_output_for_connector(struct drm_compositor *ec,
 
 	wl_list_insert(ec->base.output_list.prev, &output->base.link);
 
+	gles2_renderer_output_bind(&output->base, go);
+
 	output->base.origin = output->base.current;
 	output->base.repaint = drm_output_repaint;
 	output->base.destroy = drm_output_destroy;
@@ -1445,7 +1442,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,
@@ -2227,9 +2225,6 @@ drm_compositor_create(struct wl_display *display,
 		goto err_sprite;
 	}
 
-	if (gles2_renderer_init(&ec->base) < 0)
-		goto err_egl;
-
 	path = NULL;
 
 	evdev_input_create(&ec->base, ec->udev, seat);
@@ -2270,7 +2265,6 @@ 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);
-err_egl:
 	eglMakeCurrent(ec->base.egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
 		       EGL_NO_CONTEXT);
 	eglTerminate(ec->base.egl_display);
diff --git a/src/compositor-rpi.c b/src/compositor-rpi.c
index c4023af..3fdc26a 100644
--- a/src/compositor-rpi.c
+++ b/src/compositor-rpi.c
@@ -970,8 +970,8 @@ rpi_output_destroy(struct weston_output *base)
 	vc_dispmanx_element_remove(update, output->egl_element);
 	vc_dispmanx_update_submit_sync(update);
 
-	eglDestroySurface(output->compositor->base.egl_display,
-			  output->base.egl_surface);
+	gles2_renderer_output_state_destroy(base->compositor,
+					    base->renderer_state);
 
 	wl_list_for_each_safe(element, tmp, &output->element_list, link)
 		rpi_element_destroy(element);
@@ -997,6 +997,7 @@ rpi_output_create(struct rpi_compositor *compositor)
 	VC_RECT_T src_rect;
 	int ret;
 	float mm_width, mm_height;
+	struct gles2_output_state *go;
 	VC_DISPMANX_ALPHA_T alphasetup = {
 		DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS,
 		255, /* opacity 0-255 */
@@ -1050,23 +1051,17 @@ rpi_output_create(struct rpi_compositor *compositor)
 	output->egl_window.width = modeinfo.width;
 	output->egl_window.height = modeinfo.height;
 
-	output->base.egl_surface =
-		eglCreateWindowSurface(compositor->base.egl_display,
-				       compositor->base.egl_config,
-				       (EGLNativeWindowType)&output->egl_window,
-				       NULL);
-	if (output->base.egl_surface == EGL_NO_SURFACE) {
-		print_egl_error_state();
-		weston_log("Failed to create output surface.\n");
-		goto out_dmx;
-	}
+	go = gles2_renderer_output_state_create(&compositor->base,
+				(EGLNativeWindowType)&output->egl_window);
+	if (!go)
+		goto out_output;
 
 	if (!eglSurfaceAttrib(compositor->base.egl_display,
-			      output->base.egl_surface,
+			     gles2_renderer_output_state_surface(go),
 			      EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED)) {
 		print_egl_error_state();
 		weston_log("Failed to set swap behaviour to preserved.\n");
-		goto out_surface;
+		goto out_gles2;
 	}
 
 	output->base.repaint = rpi_output_repaint;
@@ -1106,6 +1101,8 @@ rpi_output_create(struct rpi_compositor *compositor)
 			   WL_OUTPUT_TRANSFORM_NORMAL);
 	wl_list_insert(compositor->base.output_list.prev, &output->base.link);
 
+	gles2_renderer_output_bind(&output->base, go);
+
 	weston_log("Raspberry Pi HDMI output %dx%d px\n",
 		   output->mode.width, output->mode.height);
 	weston_log_continue(STAMP_SPACE "guessing %d Hz and 96 dpi\n",
@@ -1113,11 +1110,11 @@ rpi_output_create(struct rpi_compositor *compositor)
 
 	return 0;
 
-out_surface:
-	eglDestroySurface(compositor->base.egl_display,
-			  output->base.egl_surface);
-
-out_dmx:
+out_gles2:
+	gles2_renderer_output_state_destroy(&compositor->base,
+					    output->base.renderer_state);
+out_output:
+	weston_output_destroy(&output->base);
 	update = vc_dispmanx_update_start(0);
 	vc_dispmanx_element_remove(update, output->egl_element);
 	vc_dispmanx_update_submit_sync(update);
@@ -1512,7 +1509,6 @@ rpi_compositor_create(struct wl_display *display, int argc, char *argv[],
 		      const char *config_file, struct rpi_parameters *param)
 {
 	struct rpi_compositor *compositor;
-	struct weston_output *output;
 	const char *seat = default_seat;
 	uint32_t key;
 
@@ -1571,17 +1567,10 @@ rpi_compositor_create(struct wl_display *display, int argc, char *argv[],
 	if (rpi_output_create(compositor) < 0)
 		goto out_egl;
 
-	if (gles2_renderer_init(&compositor->base) < 0)
-		goto out_output;
-
 	evdev_input_create(&compositor->base, compositor->udev, seat);
 
 	return &compositor->base;
 
-out_output:
-	wl_list_for_each(output, &compositor->base.output_list, link)
-		rpi_output_destroy(output);
-
 out_egl:
 	rpi_fini_egl(compositor);
 
diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c
index 56759fc..87c1257 100644
--- a/src/compositor-wayland.c
+++ b/src/compositor-wayland.c
@@ -317,9 +317,10 @@ 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_state_destroy(output_base->compositor,
+					    output_base->renderer_state);
+
 	wl_egl_window_destroy(output->parent.egl_window);
 	free(output);
 
@@ -333,6 +334,7 @@ wayland_compositor_create_output(struct wayland_compositor *c,
 				 int width, int height)
 {
 	struct wayland_output *output;
+	struct gles2_output_state *go;
 
 	output = malloc(sizeof *output);
 	if (output == NULL)
@@ -373,13 +375,12 @@ 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");
+	go = gles2_renderer_output_state_create(&c->base,
+			output->parent.egl_window);
+	if (!go)
 		goto cleanup_window;
-	}
+
+	gles2_renderer_output_bind(&output->base, go);
 
 	output->parent.shell_surface =
 		wl_shell_get_shell_surface(c->parent.shell,
@@ -846,10 +847,6 @@ wayland_compositor_create(struct wl_display *display,
 	if (wayland_compositor_create_output(c, width, height) < 0)
 		goto err_display;
 
-	/* requires wayland_compositor_create_output */
-	if (gles2_renderer_init(&c->base) < 0)
-		goto err_display;
-
 	/* requires gles2_renderer_init */
 	create_border(c);
 
diff --git a/src/compositor-x11.c b/src/compositor-x11.c
index 9d922b5..44370e8 100644
--- a/src/compositor-x11.c
+++ b/src/compositor-x11.c
@@ -390,8 +390,8 @@ 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_state_destroy(output_base->compositor,
+					    output_base->renderer_state);
 
 	xcb_destroy_window(compositor->conn, output->window);
 
@@ -515,6 +515,7 @@ x11_compositor_create_output(struct x11_compositor *c, int x, int y,
 	xcb_screen_iterator_t iter;
 	struct wm_normal_hints normal_hints;
 	struct wl_event_loop *loop;
+	struct gles2_output_state *go;
 	uint32_t mask = XCB_CW_EVENT_MASK | XCB_CW_CURSOR;
 	xcb_atom_t atom_list[1];
 	uint32_t values[2] = {
@@ -607,13 +608,9 @@ x11_compositor_create_output(struct x11_compositor *c, int x, int y,
 
 	x11_output_wait_for_map(c, output);
 
-	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");
+	go = gles2_renderer_output_state_create(&c->base, output->window);
+	if (!go)
 		return NULL;
-	}
 
 	loop = wl_display_get_event_loop(c->base.wl_display);
 	output->finish_frame_timer =
@@ -634,6 +631,8 @@ x11_compositor_create_output(struct x11_compositor *c, int x, int y,
 
 	wl_list_insert(c->base.output_list.prev, &output->base.link);
 
+	gles2_renderer_output_bind(&output->base, go);
+
 	weston_log("x11 output %dx%d, window id %d\n",
 		   width, height, output->window);
 
@@ -1247,9 +1246,6 @@ 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;
-
 	c->xcb_source =
 		wl_event_loop_add_fd(c->base.input_loop,
 				     xcb_get_file_descriptor(c->conn),
diff --git a/src/compositor.h b/src/compositor.h
index d2e121b..f97a29e 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -154,7 +154,8 @@ enum dpms_enum {
 struct weston_output {
 	uint32_t id;
 
-	EGLSurface egl_surface;
+	void *renderer_state;
+
 	struct wl_list link;
 	struct wl_list resource_list;
 	struct wl_global *global;
@@ -837,8 +838,19 @@ weston_surface_destroy(struct weston_surface *surface);
 int
 weston_output_switch_mode(struct weston_output *output, struct weston_mode *mode);
 
-int
-gles2_renderer_init(struct weston_compositor *ec);
+struct gles2_output_state;
+
+struct gles2_output_state *
+gles2_renderer_output_state_create(struct weston_compositor *ec,
+				   EGLNativeWindowType window);
+void
+gles2_renderer_output_state_destroy(struct weston_compositor *ec,
+				    struct gles2_output_state *go);
+EGLSurface
+gles2_renderer_output_state_surface(struct gles2_output_state *go);
+void
+gles2_renderer_output_bind(struct weston_output *output,
+			   struct gles2_output_state *go);
 void
 gles2_renderer_destroy(struct weston_compositor *ec);
 
diff --git a/src/gles2-renderer.c b/src/gles2-renderer.c
index 49fe7b0..f89d740 100644
--- a/src/gles2-renderer.c
+++ b/src/gles2-renderer.c
@@ -36,6 +36,17 @@ struct gles2_renderer {
 	int fragment_shader_debug;
 };
 
+struct gles2_output_state {
+	EGLSurface egl_surface;
+};
+
+
+static inline struct gles2_output_state *
+get_output_state(struct weston_output *output)
+{
+	return (struct gles2_output_state *)output->renderer_state;
+}
+
 static const char *
 egl_error_string(EGLint code)
 {
@@ -706,6 +717,7 @@ static void
 gles2_renderer_repaint_output(struct weston_output *output,
 			      pixman_region32_t *output_damage)
 {
+	struct gles2_output_state *go = get_output_state(output);
 	struct weston_compositor *compositor = output->compositor;
 	EGLBoolean ret;
 	static int errored;
@@ -718,8 +730,8 @@ gles2_renderer_repaint_output(struct weston_output *output,
 
 	glViewport(0, 0, width, height);
 
-	ret = eglMakeCurrent(compositor->egl_display, output->egl_surface,
-			     output->egl_surface, compositor->egl_context);
+	ret = eglMakeCurrent(compositor->egl_display, go->egl_surface,
+			     go->egl_surface, compositor->egl_context);
 	if (ret == EGL_FALSE) {
 		if (errored)
 			return;
@@ -755,7 +767,7 @@ gles2_renderer_repaint_output(struct weston_output *output,
 
 	wl_signal_emit(&output->frame_signal, output);
 
-	ret = eglSwapBuffers(compositor->egl_display, output->egl_surface);
+	ret = eglSwapBuffers(compositor->egl_display, go->egl_surface);
 	if (ret == EGL_FALSE && !errored) {
 		errored = 1;
 		weston_log("Failed in eglSwapBuffers.\n");
@@ -1213,6 +1225,60 @@ log_egl_config_info(EGLDisplay egldpy, EGLConfig eglconfig)
 		weston_log_continue(" unknown\n");
 }
 
+static int
+gles2_renderer_setup(struct weston_compositor *ec, EGLSurface egl_surface);
+
+WL_EXPORT struct gles2_output_state *
+gles2_renderer_output_state_create(struct weston_compositor *ec,
+				   EGLNativeWindowType window)
+{
+	struct gles2_output_state *go = calloc(1, sizeof *go);
+
+	if (!go)
+		return NULL;
+
+	go->egl_surface =
+		eglCreateWindowSurface(ec->egl_display,
+				       ec->egl_config,
+				       window, NULL);
+
+	if (go->egl_surface == EGL_NO_SURFACE) {
+		weston_log("failed to create egl surface\n");
+		free(go);
+		return NULL;
+	}
+
+	if (ec->egl_context == NULL)
+		if (gles2_renderer_setup(ec, go->egl_surface) < 0) {
+			free(go);
+			return NULL;
+		}
+
+	return go;
+}
+
+WL_EXPORT void
+gles2_renderer_output_state_destroy(struct weston_compositor *ec,
+				    struct gles2_output_state *go)
+{
+	eglDestroySurface(ec->egl_display, go->egl_surface);
+
+	free(go);
+}
+
+WL_EXPORT EGLSurface
+gles2_renderer_output_state_surface(struct gles2_output_state *go)
+{
+	return go->egl_surface;
+}
+
+WL_EXPORT void
+gles2_renderer_output_bind(struct weston_output *output,
+			   struct gles2_output_state *go)
+{
+	output->renderer_state = go;
+}
+
 WL_EXPORT void
 gles2_renderer_destroy(struct weston_compositor *ec)
 {
@@ -1274,12 +1340,11 @@ fragment_debug_binding(struct wl_seat *seat, uint32_t time, uint32_t key,
 		weston_output_damage(output);
 }
 
-WL_EXPORT int
-gles2_renderer_init(struct weston_compositor *ec)
+static int
+gles2_renderer_setup(struct weston_compositor *ec, EGLSurface egl_surface)
 {
 	struct gles2_renderer *renderer;
 	const char *extensions;
-	struct weston_output *output;
 	EGLBoolean ret;
 
 	static const EGLint context_attribs[] = {
@@ -1307,10 +1372,8 @@ gles2_renderer_init(struct weston_compositor *ec)
 		return -1;
 	}
 
-	output = container_of(ec->output_list.next,
-			      struct weston_output, link);
-	ret = eglMakeCurrent(ec->egl_display, output->egl_surface,
-			     output->egl_surface, ec->egl_context);
+	ret = eglMakeCurrent(ec->egl_display, egl_surface,
+			     egl_surface, ec->egl_context);
 	if (ret == EGL_FALSE) {
 		weston_log("Failed to make EGL context current.\n");
 		print_egl_error_state();
-- 
1.8.0



More information about the wayland-devel mailing list