From: Ander Conselvan de Oliveira <[email protected]>

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

_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to