[PATCH v6 01/12] Move weston_output EGL state into gles2-renderer.

Kristian Høgsberg hoegsberg at gmail.com
Tue Nov 13 13:51:58 PST 2012


On Tue, Nov 13, 2012 at 07:10:18PM +0100, John Kåre Alsaker wrote:
> This introduces callbacks for output creation and destruction for the gles2-renderer. This enables the gles2-renderer to have per-output state. EGL surface creation is now done by the output_create callback and the EGL surface is stored in the new per-output gles2-renderer state. On the first output_create call, the gles2-renderer will setup it's GL context. This is because EGL requires a EGL surface to be able to use the GL context.

Yeah, this looks good now.

However, commit subject and body should be at most 76 characters wide
(at least under 80, but git log adds four spaces in front of the
commit message, so 76 leaves enough right margin).  I've reformatted
the commit messages in this patch series, but in the future please
match the style.

Kristian

> ---
>  src/compositor-android.c | 16 +++-------
>  src/compositor-drm.c     | 50 +++++++++++-------------------
>  src/compositor-rpi.c     | 52 +++++++++++--------------------
>  src/compositor-wayland.c | 16 +++-------
>  src/compositor-x11.c     | 25 +++++----------
>  src/compositor.h         | 10 ++++--
>  src/gles2-renderer.c     | 80 ++++++++++++++++++++++++++++++++++++++++++------
>  7 files changed, 130 insertions(+), 119 deletions(-)
> 
> diff --git a/src/compositor-android.c b/src/compositor-android.c
> index 3c0273a..5bf1df3 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_destroy(base);
> +
>  	android_framebuffer_destroy(output->fb);
>  
>  	free(output);
> @@ -406,16 +408,9 @@ 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();
> +	if (gles2_renderer_output_create(&output->base,
> +			output->fb->native_window) < 0)
>  		return -1;
> -	}
>  
>  	return 0;
>  }
> @@ -478,9 +473,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..f7b8d68 100644
> --- a/src/compositor-drm.c
> +++ b/src/compositor-drm.c
> @@ -829,7 +829,8 @@ 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_destroy(output_base);
> +
>  	gbm_surface_destroy(output->surface);
>  
>  	weston_plane_release(&output->fb_plane);
> @@ -875,7 +876,6 @@ 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;
>  
>  	if (output_base == NULL) {
>  		weston_log("output is NULL.\n");
> @@ -935,14 +935,11 @@ 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);
> +	gles2_renderer_output_destroy(&output->base);
>  
> -	if (egl_surface == EGL_NO_SURFACE) {
> -		weston_log("failed to create egl surface\n");
> -		goto err;
> +	if (!gles2_renderer_output_create(&output->base, surface)) {
> +		weston_log("failed to create renderer output\n");
> +		goto err_gbm;
>  	}
>  
>  	ret = drmModeSetCrtc(ec->drm.fd,
> @@ -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,9 +970,7 @@ 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);
>  	gbm_surface_destroy(output->surface);
> -	output->base.egl_surface = egl_surface;
>  	output->surface = surface;
>  
>  	/*update output*/
> @@ -984,8 +979,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_destroy(&output->base);
> +err_gbm:
>  	gbm_surface_destroy(surface);
>  	return -1;
>  }
> @@ -1387,15 +1383,12 @@ 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);
> +
> +	if (gles2_renderer_output_create(&output->base, output->surface) < 0)
> +		goto err_output;
>  
>  	output->cursor_bo[0] =
>  		gbm_bo_create(ec->gbm, 64, 64, GBM_FORMAT_ARGB8888,
> @@ -1415,10 +1408,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;
> @@ -1445,7 +1434,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 +2217,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 +2257,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..69f3d59 100644
> --- a/src/compositor-rpi.c
> +++ b/src/compositor-rpi.c
> @@ -970,8 +970,7 @@ 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_destroy(base);
>  
>  	wl_list_for_each_safe(element, tmp, &output->element_list, link)
>  		rpi_element_destroy(element);
> @@ -1050,25 +1049,6 @@ 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;
> -	}
> -
> -	if (!eglSurfaceAttrib(compositor->base.egl_display,
> -			      output->base.egl_surface,
> -			      EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED)) {
> -		print_egl_error_state();
> -		weston_log("Failed to set swap behaviour to preserved.\n");
> -		goto out_surface;
> -	}
> -
>  	output->base.repaint = rpi_output_repaint;
>  	output->base.destroy = rpi_output_destroy;
>  	if (compositor->max_planes > 0)
> @@ -1104,6 +1084,19 @@ rpi_output_create(struct rpi_compositor *compositor)
>  	weston_output_init(&output->base, &compositor->base,
>  			   0, 0, round(mm_width), round(mm_height),
>  			   WL_OUTPUT_TRANSFORM_NORMAL);
> +
> +	if (gles2_renderer_output_create(&output->base,
> +			(EGLNativeWindowType)&output->egl_window) < 0)
> +		goto out_output;
> +
> +	if (!eglSurfaceAttrib(compositor->base.egl_display,
> +			     gles2_renderer_output_surface(&output->base),
> +			      EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED)) {
> +		print_egl_error_state();
> +		weston_log("Failed to set swap behaviour to preserved.\n");
> +		goto out_gles2;
> +	}
> +
>  	wl_list_insert(compositor->base.output_list.prev, &output->base.link);
>  
>  	weston_log("Raspberry Pi HDMI output %dx%d px\n",
> @@ -1113,11 +1106,10 @@ 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_destroy(&output->base);
> +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 +1504,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 +1562,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..db97713 100644
> --- a/src/compositor-wayland.c
> +++ b/src/compositor-wayland.c
> @@ -317,9 +317,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_destroy(output_base);
> +
>  	wl_egl_window_destroy(output->parent.egl_window);
>  	free(output);
>  
> @@ -373,13 +373,9 @@ 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_output_create(&output->base,
> +			output->parent.egl_window) < 0)
>  		goto cleanup_window;
> -	}
>  
>  	output->parent.shell_surface =
>  		wl_shell_get_shell_surface(c->parent.shell,
> @@ -846,10 +842,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..cbb2482 100644
> --- a/src/compositor-x11.c
> +++ b/src/compositor-x11.c
> @@ -390,8 +390,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_destroy(output_base);
>  
>  	xcb_destroy_window(compositor->conn, output->window);
>  
> @@ -607,18 +606,6 @@ 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");
> -		return NULL;
> -	}
> -
> -	loop = wl_display_get_event_loop(c->base.wl_display);
> -	output->finish_frame_timer =
> -		wl_event_loop_add_timer(loop, finish_frame_handler, output);
> -
>  	output->base.origin = output->base.current;
>  	output->base.repaint = x11_output_repaint;
>  	output->base.destroy = x11_output_destroy;
> @@ -632,6 +619,13 @@ x11_compositor_create_output(struct x11_compositor *c, int x, int y,
>  	weston_output_init(&output->base, &c->base,
>  			   x, y, width, height, transform);
>  
> +	if (gles2_renderer_output_create(&output->base, output->window) < 0)
> +		return NULL;
> +
> +	loop = wl_display_get_event_loop(c->base.wl_display);
> +	output->finish_frame_timer =
> +		wl_event_loop_add_timer(loop, finish_frame_handler, output);
> +
>  	wl_list_insert(c->base.output_list.prev, &output->base.link);
>  
>  	weston_log("x11 output %dx%d, window id %d\n",
> @@ -1247,9 +1241,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..1826594 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;
> @@ -838,7 +839,12 @@ int
>  weston_output_switch_mode(struct weston_output *output, struct weston_mode *mode);
>  
>  int
> -gles2_renderer_init(struct weston_compositor *ec);
> +gles2_renderer_output_create(struct weston_output *output,
> +				    EGLNativeWindowType window);
> +void
> +gles2_renderer_output_destroy(struct weston_output *output);
> +EGLSurface
> +gles2_renderer_output_surface(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 49fe7b0..2559602 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,57 @@ 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 int
> +gles2_renderer_output_create(struct weston_output *output,
> +				    EGLNativeWindowType window)
> +{
> +	struct weston_compositor *ec = output->compositor;
> +	struct gles2_output_state *go = calloc(1, sizeof *go);
> +
> +	if (!go)
> +		return -1;
> +
> +	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 -1;
> +	}
> +
> +	if (ec->egl_context == NULL)
> +		if (gles2_renderer_setup(ec, go->egl_surface) < 0) {
> +			free(go);
> +			return -1;
> +		}
> +
> +	output->renderer_state = go;
> +
> +	return 0;
> +}
> +
> +WL_EXPORT void
> +gles2_renderer_output_destroy(struct weston_output *output)
> +{
> +	struct gles2_output_state *go = get_output_state(output);
> +
> +	eglDestroySurface(output->compositor->egl_display, go->egl_surface);
> +
> +	free(go);
> +}
> +
> +WL_EXPORT EGLSurface
> +gles2_renderer_output_surface(struct weston_output *output)
> +{
> +	return get_output_state(output)->egl_surface;
> +}
> +
>  WL_EXPORT void
>  gles2_renderer_destroy(struct weston_compositor *ec)
>  {
> @@ -1274,12 +1337,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 +1369,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
> 
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel


More information about the wayland-devel mailing list