[PATCH 5/9] compositor: Change API to better handle mode switches. Also moves EGLSurface into gles2-renderer.

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


---
 src/compositor-android.c |  2 +-
 src/compositor-drm.c     | 19 +++++++++---------
 src/compositor-wayland.c |  2 +-
 src/compositor-x11.c     |  2 +-
 src/compositor.h         | 13 ++++++------
 src/gles2-renderer.c     | 52 +++++++++++++++++++++++++++++-------------------
 6 files changed, 52 insertions(+), 38 deletions(-)

diff --git a/src/compositor-android.c b/src/compositor-android.c
index 753413d..953c25d 100644
--- a/src/compositor-android.c
+++ b/src/compositor-android.c
@@ -407,7 +407,7 @@ android_init_egl(struct android_compositor *compositor,
 
 	gles2_renderer_select_config(&compositor->base, egl_config);
 
-	if(gles2_renderer_surface_create_and_bind(&output->base, output->fb->native_window) < 0)
+	if(gles2_renderer_output_state_create_and_bind(&output->base, output->fb->native_window) < 0)
 		return -1;
 
 	return 0;
diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index cba202e..c66c0ae 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -908,7 +908,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 *state;
 
 	if (output_base == NULL) {
 		weston_log("output is NULL.\n");
@@ -968,10 +968,10 @@ drm_output_switch_mode(struct weston_output *output_base, struct weston_mode *mo
 		return -1;
 	}
 
-	egl_surface = gles2_renderer_surface_create(&ec->base, surface);
+	state = gles2_renderer_output_state_create(&ec->base, surface);
 
-	if (egl_surface == EGL_NO_SURFACE)
-		goto err;
+	if (!state)
+		goto err_gbm;
 
 	ret = drmModeSetCrtc(ec->drm.fd,
 			     output->crtc_id,
@@ -979,7 +979,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. */
@@ -1004,7 +1004,7 @@ drm_output_switch_mode(struct weston_output *output_base, struct weston_mode *mo
 	gles2_renderer_output_unbind(output_base);
 	gbm_surface_destroy(output->surface);
 	output->surface = surface;
-	gles2_renderer_output_bind(&output->base, egl_surface);
+	gles2_renderer_output_bind(&output->base, state);
 
 	/*update output*/
 	output->base.current = &drm_mode->base;
@@ -1012,8 +1012,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:
-	gles2_renderer_surface_destroy(&ec->base, egl_surface);
+err_gles2:
+	gles2_renderer_output_state_destroy(&ec->base, state);
+err_gbm:
 	gbm_surface_destroy(surface);
 	return -1;
 }
@@ -1423,7 +1424,7 @@ create_output_for_connector(struct drm_compositor *ec,
 			   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)
+	if(gles2_renderer_output_state_create_and_bind(&output->base, output->surface) < 0)
 		goto err_output;
 
 	output->cursor_bo[0] =
diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c
index 9a12b1d..71031ff 100644
--- a/src/compositor-wayland.c
+++ b/src/compositor-wayland.c
@@ -337,7 +337,7 @@ wayland_compositor_create_output(struct wayland_compositor *c,
 		goto cleanup_output;
 	}
 
-	if(gles2_renderer_surface_create_and_bind(&output->base, output->parent.egl_window) < 0)
+	if(gles2_renderer_output_state_create_and_bind(&output->base, output->parent.egl_window) < 0)
 		goto cleanup_window;
 
 	output->parent.shell_surface =
diff --git a/src/compositor-x11.c b/src/compositor-x11.c
index 828c9fd..bac519c 100644
--- a/src/compositor-x11.c
+++ b/src/compositor-x11.c
@@ -478,7 +478,7 @@ x11_compositor_create_output(struct x11_compositor *c, int x, int y,
 		x11_output_change_state(output, 1,
 					c->atom.net_wm_state_fullscreen);
 
-	if(gles2_renderer_surface_create_and_bind(&output->base, output->window) < 0)
+	if(gles2_renderer_output_state_create_and_bind(&output->base, output->window) < 0)
 		return NULL;
 
 	loop = wl_display_get_event_loop(c->base.wl_display);
diff --git a/src/compositor.h b/src/compositor.h
index 3a9f4bc..dabaf9e 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -151,7 +151,6 @@ struct weston_output {
 
 	void *renderer_state;
 
-	EGLSurface egl_surface;
 	struct wl_list link;
 	struct wl_list resource_list;
 	struct wl_global *global;
@@ -802,6 +801,8 @@ weston_surface_destroy(struct weston_surface *surface);
 int
 weston_output_switch_mode(struct weston_output *output, struct weston_mode *mode);
 
+struct gles2_output_state;
+
 int
 gles2_renderer_init(struct weston_compositor *ec, EGLNativeDisplayType display, int alpha);
 EGLDisplay
@@ -813,13 +814,13 @@ gles2_renderer_outputs_ready(struct weston_compositor *ec);
 void
 gles2_renderer_use_rgba_shader(struct weston_output *output);
 int
-gles2_renderer_surface_create_and_bind(struct weston_output *output, EGLNativeWindowType window);
-EGLSurface
-gles2_renderer_surface_create(struct weston_compositor *ec, EGLNativeWindowType window);
+gles2_renderer_output_state_create_and_bind(struct weston_output *output, EGLNativeWindowType window);
+struct gles2_output_state *
+gles2_renderer_output_state_create(struct weston_compositor *ec, EGLNativeWindowType window);
 void
-gles2_renderer_surface_destroy(struct weston_compositor *ec, EGLSurface surface);
+gles2_renderer_output_state_destroy(struct weston_compositor *ec, struct gles2_output_state *state);
 void
-gles2_renderer_output_bind(struct weston_output *output, EGLSurface surface);
+gles2_renderer_output_bind(struct weston_output *output, struct gles2_output_state *state);
 void
 gles2_renderer_output_unbind(struct weston_output *output);
 void
diff --git a/src/gles2-renderer.c b/src/gles2-renderer.c
index abd2a37..37e9b76 100644
--- a/src/gles2-renderer.c
+++ b/src/gles2-renderer.c
@@ -31,6 +31,7 @@
 #include "compositor.h"
 
 struct gles2_output_state {
+	EGLSurface egl_surface;
 };
 
 struct gles2_surface_state {
@@ -728,6 +729,7 @@ static void
 gles2_renderer_repaint_output(struct weston_output *output,
 			      pixman_region32_t *output_damage)
 {
+	struct gles2_output_state *output_state = get_output_state(output);
 	struct weston_compositor *compositor = output->compositor;
 	EGLBoolean ret;
 	static int errored;
@@ -740,8 +742,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, output_state->egl_surface,
+			     output_state->egl_surface, compositor->egl_context);
 	if (ret == EGL_FALSE) {
 		if (errored)
 			return;
@@ -777,7 +779,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, output_state->egl_surface);
 	if (ret == EGL_FALSE && !errored) {
 		errored = 1;
 		weston_log("Failed in eglSwapBuffers.\n");
@@ -1237,48 +1239,58 @@ gles2_renderer_use_rgba_shader(struct weston_output *output)
 }
 
 WL_EXPORT int
-gles2_renderer_surface_create_and_bind(struct weston_output *output, EGLNativeWindowType window)
+gles2_renderer_output_state_create_and_bind(struct weston_output *output, EGLNativeWindowType window)
 {
-	EGLSurface surface = gles2_renderer_surface_create(output->compositor, window);
+	struct gles2_output_state *state = gles2_renderer_output_state_create(output->compositor, window);
 
-	if (surface == EGL_NO_SURFACE)
+	if (!state)
 		return -1;
 
-	gles2_renderer_output_bind(output, surface);
+	gles2_renderer_output_bind(output, state);
 
 	return 0;
 }
 
-WL_EXPORT EGLSurface
-gles2_renderer_surface_create(struct weston_compositor *ec, EGLNativeWindowType window)
+WL_EXPORT struct gles2_output_state *
+gles2_renderer_output_state_create(struct weston_compositor *ec, EGLNativeWindowType window)
 {
-	EGLSurface surface =
+	struct gles2_output_state *state = calloc(1, sizeof *state);
+
+	if(!state)
+		return NULL;
+
+	state->egl_surface =
 		eglCreateWindowSurface(ec->egl_display,
 				       ec->egl_config,
 				       window, NULL);
 
-	if (surface == EGL_NO_SURFACE)
+	if (state->egl_surface == EGL_NO_SURFACE) {
 		weston_log("failed to create egl surface\n");
+		free(state);
+		return NULL;
+	}
 
-	return surface;
+	return state;
 }
 
 WL_EXPORT void
-gles2_renderer_surface_destroy(struct weston_compositor *ec, EGLSurface surface)
+gles2_renderer_output_state_destroy(struct weston_compositor *ec, struct gles2_output_state *state)
 {
-	eglDestroySurface(ec->egl_display, surface);
+	eglDestroySurface(ec->egl_display, state->egl_surface);
+
+	free(state);
 }
 
 WL_EXPORT void
-gles2_renderer_output_bind(struct weston_output *output, EGLSurface surface)
+gles2_renderer_output_bind(struct weston_output *output, struct gles2_output_state *state)
 {
-	output->egl_surface = surface;
+	output->renderer_state = state;
 }
 
 WL_EXPORT void
 gles2_renderer_output_unbind(struct weston_output *output)
 {
-	gles2_renderer_surface_destroy(output->compositor, output->egl_surface);
+	gles2_renderer_output_state_destroy(output->compositor, get_output_state(output));
 }
 
 WL_EXPORT void
@@ -1344,7 +1356,7 @@ gles2_renderer_outputs_ready(struct weston_compositor *ec)
 {
 	const char *extensions;
 	int has_egl_image_external = 0;
-	struct weston_output *output;
+	struct gles2_output_state *output;
 	EGLBoolean ret;
 
 	static const EGLint context_attribs[] = {
@@ -1365,8 +1377,8 @@ gles2_renderer_outputs_ready(struct weston_compositor *ec)
 		return -1;
 	}
 
-	output = container_of(ec->output_list.next,
-			      struct weston_output, link);
+	output = get_output_state(container_of(ec->output_list.next,
+			      struct weston_output, link));
 	ret = eglMakeCurrent(ec->egl_display, output->egl_surface,
 			     output->egl_surface, ec->egl_context);
 	if (ret == EGL_FALSE) {
-- 
1.7.12



More information about the wayland-devel mailing list