From 361d2ade0246f87a2cb67a9d0b5231b886bdd28a Mon Sep 17 00:00:00 2001 From: Matt Roper Date: Mon, 29 Aug 2011 13:52:23 -0700 Subject: [PATCH] Update compositor shutdown code Adds a general wlsc_compositor_shutdown() function that all output backends call when shutting down. wlsc_compositor_shutdown() will call a new 'destroy' method of each output to perform backend-specific cleanup (e.g., turning off the hardware cursor in the DRM compositor). Signed-off-by: Matt Roper --- compositor/compositor-drm.c | 33 +++++++++++++++++++++++++++++++++ compositor/compositor-openwfd.c | 11 +++++++++++ compositor/compositor-wayland.c | 16 ++++++++++++++++ compositor/compositor-x11.c | 8 ++++++++ compositor/compositor.c | 10 ++++++++++ compositor/compositor.h | 3 +++ 6 files changed, 81 insertions(+) diff --git a/compositor/compositor-drm.c b/compositor/compositor-drm.c index c28c7d2d..b5fa28de 100644 --- a/compositor/compositor-drm.c +++ b/compositor/compositor-drm.c @@ -59,6 +59,7 @@ struct drm_output { uint32_t crtc_id; uint32_t connector_id; + drmModeCrtcPtr original_crtc; GLuint rbo[2]; uint32_t fb_id[2]; EGLImageKHR image[2]; @@ -255,6 +256,33 @@ out: return ret; } +static void +drm_output_destroy(struct wlsc_output *output_base) +{ + struct drm_output *output = (struct drm_output *) output_base; + struct drm_compositor *c = + (struct drm_compositor *) output_base->compositor; + drmModeCrtcPtr origcrtc = output->original_crtc; + int i; + + /* Turn off hardware cursor */ + drm_output_set_cursor(output_base, NULL); + + /* Restore original CRTC state */ + drmModeSetCrtc(c->drm.fd, origcrtc->crtc_id, origcrtc->buffer_id, + origcrtc->x, origcrtc->y, &output->connector_id, 1, &origcrtc->mode); + drmModeFreeCrtc(origcrtc); + + /* Destroy output buffers */ + for (i = 0; i < 2; i++) { + drmModeRmFB(c->drm.fd, output->fb_id[i]); + c->base.destroy_image(c->base.display, output->image[i]); + gbm_bo_destroy(output->bo[i]); + } + + free(output); +} + static int on_drm_input(int fd, uint32_t mask, void *data) { @@ -422,6 +450,8 @@ create_output_for_connector(struct drm_compositor *ec, output->connector_id = connector->connector_id; ec->connector_allocator |= (1 << output->connector_id); + output->original_crtc = drmModeGetCrtc(ec->drm.fd, output->crtc_id); + for (i = 0; i < connector->count_modes; i++) drm_output_add_mode(output, &connector->modes[i]); if (connector->count_modes == 0) @@ -491,6 +521,7 @@ create_output_for_connector(struct drm_compositor *ec, output->base.prepare_scanout_surface = drm_output_prepare_scanout_surface; output->base.set_hardware_cursor = drm_output_set_cursor; + output->base.destroy = drm_output_destroy; return 0; } @@ -724,6 +755,8 @@ drm_destroy(struct wlsc_compositor *ec) { struct drm_compositor *d = (struct drm_compositor *) ec; + wlsc_compositor_shutdown(ec); + gbm_device_destroy(d->gbm); tty_destroy(d->tty); free(d); diff --git a/compositor/compositor-openwfd.c b/compositor/compositor-openwfd.c index 672e723b..d4436e3d 100644 --- a/compositor/compositor-openwfd.c +++ b/compositor/compositor-openwfd.c @@ -187,6 +187,14 @@ wfd_output_set_cursor(struct wlsc_output *output_base, return -1; } +static void +wfd_output_destroy(struct wlsc_output *output_base) +{ + destroy_output(output_base); + + return; +} + static int wfd_output_add_mode(struct wfd_output *output, WFDPortMode mode) { @@ -374,6 +382,7 @@ create_output_for_port(struct wfd_compositor *ec, output->base.prepare_scanout_surface = wfd_output_prepare_scanout_surface; output->base.set_hardware_cursor = wfd_output_set_cursor; + output->base.destroy = wfd_output_destroy; wl_list_insert(ec->base.output_list.prev, &output->base.link); @@ -572,6 +581,8 @@ wfd_destroy(struct wlsc_compositor *ec) { struct wfd_compositor *d = (struct wfd_compositor *) ec; + wlsc_compositor_shutdown(ec); + udev_unref(d->udev); wfdDestroyDevice(d->dev); diff --git a/compositor/compositor-wayland.c b/compositor/compositor-wayland.c index f547c624..df63daf3 100644 --- a/compositor/compositor-wayland.c +++ b/compositor/compositor-wayland.c @@ -212,6 +212,19 @@ wayland_output_set_cursor(struct wlsc_output *output_base, return -1; } +static void +wayland_output_destroy(struct wlsc_output *output_base) +{ + struct wayland_output *output = (struct wayland_output *) output_base; + struct wlsc_compositor *ec = output->base.compositor; + + eglDestroySurface(ec->display, output->egl_surface); + wl_egl_window_destroy(output->parent.egl_window); + free(output); + + return; +} + static int wayland_compositor_create_output(struct wayland_compositor *c, int width, int height) @@ -271,6 +284,7 @@ wayland_compositor_create_output(struct wayland_compositor *c, output->base.prepare_scanout_surface = wayland_output_prepare_scanout_surface; output->base.set_hardware_cursor = wayland_output_set_cursor; + output->base.destroy = wayland_output_destroy; wl_list_insert(c->base.output_list.prev, &output->base.link); @@ -510,6 +524,8 @@ wayland_compositor_handle_event(int fd, uint32_t mask, void *data) static void wayland_destroy(struct wlsc_compositor *ec) { + wlsc_compositor_shutdown(ec); + free(ec); } diff --git a/compositor/compositor-x11.c b/compositor/compositor-x11.c index 0825f1a1..f959e78d 100644 --- a/compositor/compositor-x11.c +++ b/compositor/compositor-x11.c @@ -209,6 +209,11 @@ x11_output_set_cursor(struct wlsc_output *output_base, return -1; } +static void +x11_output_destroy(struct wlsc_output *output_base) +{ + return; +} static void x11_output_set_wm_protocols(struct x11_output *output) @@ -408,6 +413,7 @@ x11_compositor_create_output(struct x11_compositor *c, int x, int y, output->base.prepare_scanout_surface = x11_output_prepare_scanout_surface; output->base.set_hardware_cursor = x11_output_set_cursor; + output->base.destroy = x11_output_destroy; wl_list_insert(c->base.output_list.prev, &output->base.link); @@ -679,6 +685,8 @@ x11_compositor_get_resources(struct x11_compositor *c) static void x11_destroy(struct wlsc_compositor *ec) { + wlsc_compositor_shutdown(ec); + free(ec); } diff --git a/compositor/compositor.c b/compositor/compositor.c index b2342b4c..bf312207 100644 --- a/compositor/compositor.c +++ b/compositor/compositor.c @@ -1956,6 +1956,16 @@ wlsc_compositor_init(struct wlsc_compositor *ec, struct wl_display *display) return 0; } +WL_EXPORT int +wlsc_compositor_shutdown(struct wlsc_compositor *ec) +{ + struct wlsc_output *output; + + /* Destroy all outputs associated with this compositor */ + wl_list_for_each(output, &ec->output_list, link) + output->destroy(output); +} + static int on_term_signal(int signal_number, void *data) { struct wl_display *display = data; diff --git a/compositor/compositor.h b/compositor/compositor.h index ea6e9e7a..db23c435 100644 --- a/compositor/compositor.h +++ b/compositor/compositor.h @@ -87,6 +87,7 @@ struct wlsc_output { struct wlsc_surface *es); int (*set_hardware_cursor)(struct wlsc_output *output, struct wlsc_input_device *input); + void (*destroy)(struct wlsc_output *output); }; enum wlsc_pointer_type { @@ -350,6 +351,8 @@ wlsc_compositor_get_time(void); int wlsc_compositor_init(struct wlsc_compositor *ec, struct wl_display *display); +int +wlsc_compositor_shutdown(struct wlsc_compositor *ec); void wlsc_output_move(struct wlsc_output *output, int x, int y); void