compositor-drm: Add key binding to switch from pixman to GL renderer

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.
dev
Ander Conselvan de Oliveira 11 years ago committed by Kristian Høgsberg
parent b188e912c3
commit 65796816b9
  1. 83
      src/compositor-drm.c
  2. 6
      src/gl-renderer.c

@ -596,7 +596,8 @@ drm_output_repaint(struct weston_output *output_base,
return -1; return -1;
mode = container_of(output->base.current_mode, struct drm_mode, base); 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, ret = drmModeSetCrtc(compositor->drm.fd, output->crtc_id,
output->next->fb_id, 0, 0, output->next->fb_id, 0, 0,
&output->connector_id, 1, &output->connector_id, 1,
@ -1286,15 +1287,15 @@ init_drm(struct drm_compositor *ec, struct udev_device *device)
return 0; return 0;
} }
static int static struct gbm_device *
init_egl(struct drm_compositor *ec) create_gbm_device(int fd)
{ {
EGLint format; struct gbm_device *gbm;
gl_renderer = weston_load_module("gl-renderer.so", gl_renderer = weston_load_module("gl-renderer.so",
"gl_renderer_interface"); "gl_renderer_interface");
if (!gl_renderer) if (!gl_renderer)
return -1; return NULL;
/* GBM will load a dri driver, but even though they need symbols from /* 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 * 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. */ * Workaround this by dlopen()'ing libglapi with RTLD_GLOBAL. */
dlopen("libglapi.so.0", RTLD_LAZY | 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 gbm;
return -1; }
static int
drm_compositor_create_gl_renderer(struct drm_compositor *ec)
{
EGLint format;
format = ec->format; format = ec->format;
if (gl_renderer->create(&ec->base, ec->gbm, if (gl_renderer->create(&ec->base, ec->gbm,
gl_renderer->opaque_attribs, &format) < 0) { 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); gbm_device_destroy(ec->gbm);
return -1; return -1;
} }
@ -2585,6 +2606,50 @@ recorder_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
} }
#endif #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 * static struct weston_compositor *
drm_compositor_create(struct wl_display *display, drm_compositor_create(struct wl_display *display,
struct drm_parameters *param, struct drm_parameters *param,
@ -2734,6 +2799,8 @@ drm_compositor_create(struct wl_display *display,
planes_binding, ec); planes_binding, ec);
weston_compositor_add_debug_binding(&ec->base, KEY_Q, weston_compositor_add_debug_binding(&ec->base, KEY_Q,
recorder_binding, ec); recorder_binding, ec);
weston_compositor_add_debug_binding(&ec->base, KEY_W,
renderer_switch_binding, ec);
return &ec->base; return &ec->base;

@ -511,6 +511,12 @@ draw_view(struct weston_view *ev, struct weston_output *output,
GLint filter; GLint filter;
int i; 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_init(&repaint);
pixman_region32_intersect(&repaint, pixman_region32_intersect(&repaint,
&ev->transform.boundingbox, damage); &ev->transform.boundingbox, damage);

Loading…
Cancel
Save