[PATCH 1/3] compositor-drm: Add key binding to switch from pixman to GL renderer

Ander Conselvan de Oliveira conselvan2 at gmail.com
Tue Nov 19 01:30:10 PST 2013


From: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira at intel.com>

When running with the pixman renderer, the debug binding 'W'
(mod-shift-space W) will cause the compositor to load gl-renderer.so
and start using it instead of the pixman renderer.
---
 src/compositor-drm.c |   83 +++++++++++++++++++++++++++++++++++++++++++++-----
 src/gl-renderer.c    |    6 ++++
 2 files changed, 81 insertions(+), 8 deletions(-)

diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index d4fc871..5cb0fab 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -596,7 +596,8 @@ drm_output_repaint(struct weston_output *output_base,
 		return -1;
 
 	mode = container_of(output->base.current_mode, struct drm_mode, base);
-	if (!output->current) {
+	if (!output->current ||
+	    output->current->stride != output->next->stride) {
 		ret = drmModeSetCrtc(compositor->drm.fd, output->crtc_id,
 				     output->next->fb_id, 0, 0,
 				     &output->connector_id, 1,
@@ -1286,15 +1287,15 @@ init_drm(struct drm_compositor *ec, struct udev_device *device)
 	return 0;
 }
 
-static int
-init_egl(struct drm_compositor *ec)
+static struct gbm_device *
+create_gbm_device(int fd)
 {
-	EGLint format;
+	struct gbm_device *gbm;
 
 	gl_renderer = weston_load_module("gl-renderer.so",
 					 "gl_renderer_interface");
 	if (!gl_renderer)
-		return -1;
+		return NULL;
 
 	/* GBM will load a dri driver, but even though they need symbols from
 	 * libglapi, in some version of Mesa they are not linked to it. Since
@@ -1303,14 +1304,34 @@ init_egl(struct drm_compositor *ec)
 	 * Workaround this by dlopen()'ing libglapi with RTLD_GLOBAL. */
 	dlopen("libglapi.so.0", RTLD_LAZY | RTLD_GLOBAL);
 
-	ec->gbm = gbm_create_device(ec->drm.fd);
+	gbm = gbm_create_device(fd);
 
-	if (!ec->gbm)
-		return -1;
+	return gbm;
+}
+
+static int
+drm_compositor_create_gl_renderer(struct drm_compositor *ec)
+{
+	EGLint format;
 
 	format = ec->format;
 	if (gl_renderer->create(&ec->base, ec->gbm,
 			       gl_renderer->opaque_attribs, &format) < 0) {
+		return -1;
+	}
+
+	return 0;
+}
+
+static int
+init_egl(struct drm_compositor *ec)
+{
+	ec->gbm = create_gbm_device(ec->drm.fd);
+
+	if (!ec->gbm)
+		return -1;
+
+	if (drm_compositor_create_gl_renderer(ec) < 0) {
 		gbm_device_destroy(ec->gbm);
 		return -1;
 	}
@@ -2585,6 +2606,50 @@ recorder_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
 }
 #endif
 
+static void
+switch_to_gl_renderer(struct drm_compositor *c)
+{
+	struct drm_output *output;
+
+	if (!c->use_pixman)
+		return;
+
+	weston_log("Switching to GL renderer\n");
+
+	c->gbm = create_gbm_device(c->drm.fd);
+	if (!c->gbm) {
+		weston_log("Failed to create gbm device. "
+			   "Aborting renderer switch\n");
+		return;
+	}
+
+	wl_list_for_each(output, &c->base.output_list, base.link)
+		pixman_renderer_output_destroy(&output->base);
+
+	c->base.renderer->destroy(&c->base);
+
+	if (drm_compositor_create_gl_renderer(c) < 0) {
+		gbm_device_destroy(c->gbm);
+		weston_log("Failed to create GL renderer. Quitting.\n");
+		/* FIXME: we need a function to shutdown cleanly */
+		assert(0);
+	}
+
+	wl_list_for_each(output, &c->base.output_list, base.link)
+		drm_output_init_egl(output, c);
+
+	c->use_pixman = 0;
+}
+
+static void
+renderer_switch_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
+			void *data)
+{
+	struct drm_compositor *c = (struct drm_compositor *) seat->compositor;
+
+	switch_to_gl_renderer(c);
+}
+
 static struct weston_compositor *
 drm_compositor_create(struct wl_display *display,
 		      struct drm_parameters *param,
@@ -2734,6 +2799,8 @@ drm_compositor_create(struct wl_display *display,
 					    planes_binding, ec);
 	weston_compositor_add_debug_binding(&ec->base, KEY_Q,
 					    recorder_binding, ec);
+	weston_compositor_add_debug_binding(&ec->base, KEY_W,
+					    renderer_switch_binding, ec);
 
 	return &ec->base;
 
diff --git a/src/gl-renderer.c b/src/gl-renderer.c
index 7a535c7..5e1b396 100644
--- a/src/gl-renderer.c
+++ b/src/gl-renderer.c
@@ -511,6 +511,12 @@ draw_view(struct weston_view *ev, struct weston_output *output,
 	GLint filter;
 	int i;
 
+	/* In case of a runtime switch of renderers, we may not have received
+	 * an attach for this surface since the switch. In that case we don't
+	 * have a valid buffer or a proper shader set up so skip rendering. */
+	if (!gs->shader)
+		return;
+
 	pixman_region32_init(&repaint);
 	pixman_region32_intersect(&repaint,
 				  &ev->transform.boundingbox, damage);
-- 
1.7.9.5



More information about the wayland-devel mailing list