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.
This commit is contained in:
committed by
Kristian Høgsberg
parent
b188e912c3
commit
65796816b9
+75
-8
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user