Update compositor shutdown code
authorMatt Roper <matthew.d.roper@intel.com>
Mon, 29 Aug 2011 20:52:23 +0000 (13:52 -0700)
committerKristian Høgsberg <krh@bitplanet.net>
Mon, 29 Aug 2011 21:12:27 +0000 (17:12 -0400)
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 <matthew.d.roper@intel.com>
compositor/compositor-drm.c
compositor/compositor-openwfd.c
compositor/compositor-wayland.c
compositor/compositor-x11.c
compositor/compositor.c
compositor/compositor.h

index c28c7d2..b5fa28d 100644 (file)
@@ -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);
index 672e723..d4436e3 100644 (file)
@@ -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);
index f547c62..df63daf 100644 (file)
@@ -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);
 }
 
index 0825f1a..f959e78 100644 (file)
@@ -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);
 }
 
index b2342b4..bf31220 100644 (file)
@@ -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;
index ea6e9e7..db23c43 100644 (file)
@@ -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