compositor: set surface->plane from destroyed plane to NULL
authorXiong Zhang <xiong.y.zhang@intel.com>
Wed, 23 Oct 2013 05:58:31 +0000 (13:58 +0800)
committerKristian Høgsberg <krh@bitplanet.net>
Thu, 24 Oct 2013 05:23:28 +0000 (22:23 -0700)
In drm backend, the cursor_surface->plane point to
drm_output->cursor_plane.when this output is removed,
drm_output->cursor_plane is destroyed, butcursor_surface->plane
still point to destroyed plane. So once mouse move to this
cursor_surface and system will repaint this cursor_surface,
segment fault will generate in weston_surface_damage_below() function.

V2:
-set surface->plane to NULL whose plane point to unplugged output,
 then change weston_surface_damage_below() to do nothing if
 surface->plane is NULL (Kristian)
-set surface->plane to NULL in weston_surface_unmap(),
 so that all surfaces that have a non-NULL plane pointer wil be
 on compositor->surface_list (Kristian).

bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=69777

Signed-off-by: Xiong Zhang <xiong.y.zhang@intel.com>
src/compositor-drm.c
src/compositor.c
src/compositor.h

index e32e4a8..461fce7 100644 (file)
@@ -2012,8 +2012,8 @@ create_output_for_connector(struct drm_compositor *ec,
        output->base.gamma_size = output->original_crtc->gamma_size;
        output->base.set_gamma = drm_output_set_gamma;
 
-       weston_plane_init(&output->cursor_plane, 0, 0);
-       weston_plane_init(&output->fb_plane, 0, 0);
+       weston_plane_init(&output->cursor_plane, &ec->base, 0, 0);
+       weston_plane_init(&output->fb_plane, &ec->base, 0, 0);
 
        weston_compositor_stack_plane(&ec->base, &output->cursor_plane, NULL);
        weston_compositor_stack_plane(&ec->base, &output->fb_plane,
@@ -2088,7 +2088,7 @@ create_sprites(struct drm_compositor *ec)
                memcpy(sprite->formats, plane->formats,
                       plane->count_formats * sizeof(plane->formats[0]));
                drmModeFreePlane(plane);
-               weston_plane_init(&sprite->plane, 0, 0);
+               weston_plane_init(&sprite->plane, &ec->base, 0, 0);
                weston_compositor_stack_plane(&ec->base, &sprite->plane,
                                              &ec->base.primary_plane);
 
index 11f582e..632bbe7 100644 (file)
@@ -371,7 +371,7 @@ weston_view_create(struct weston_surface *surface)
        wl_list_init(&view->link);
        wl_list_init(&view->layer_link);
 
-       view->plane = &surface->compositor->primary_plane;
+       view->plane = NULL;
 
        pixman_region32_init(&view->clip);
 
@@ -610,8 +610,9 @@ weston_view_damage_below(struct weston_view *view)
        pixman_region32_init(&damage);
        pixman_region32_subtract(&damage, &view->transform.boundingbox,
                                 &view->clip);
-       pixman_region32_union(&view->plane->damage,
-                             &view->plane->damage, &damage);
+       if (view->plane)
+               pixman_region32_union(&view->plane->damage,
+                                     &view->plane->damage, &damage);
        pixman_region32_fini(&damage);
 }
 
@@ -1147,6 +1148,7 @@ weston_view_unmap(struct weston_view *view)
 
        weston_view_damage_below(view);
        view->output = NULL;
+       view->plane = NULL;
        wl_list_remove(&view->layer_link);
        wl_list_init(&view->layer_link);
        wl_list_remove(&view->link);
@@ -2844,12 +2846,15 @@ idle_handler(void *data)
 }
 
 WL_EXPORT void
-weston_plane_init(struct weston_plane *plane, int32_t x, int32_t y)
+weston_plane_init(struct weston_plane *plane,
+                       struct weston_compositor *ec,
+                       int32_t x, int32_t y)
 {
        pixman_region32_init(&plane->damage);
        pixman_region32_init(&plane->clip);
        plane->x = x;
        plane->y = y;
+       plane->compositor = ec;
 
        /* Init the link so that the call to wl_list_remove() when releasing
         * the plane without ever stacking doesn't lead to a crash */
@@ -2859,9 +2864,16 @@ weston_plane_init(struct weston_plane *plane, int32_t x, int32_t y)
 WL_EXPORT void
 weston_plane_release(struct weston_plane *plane)
 {
+       struct weston_view *view;
+
        pixman_region32_fini(&plane->damage);
        pixman_region32_fini(&plane->clip);
 
+       wl_list_for_each(view, &plane->compositor->view_list, link) {
+               if (view->plane == plane)
+                       view->plane = NULL;
+       }
+
        wl_list_remove(&plane->link);
 }
 
@@ -3256,7 +3268,7 @@ weston_compositor_init(struct weston_compositor *ec,
        wl_list_init(&ec->axis_binding_list);
        wl_list_init(&ec->debug_binding_list);
 
-       weston_plane_init(&ec->primary_plane, 0, 0);
+       weston_plane_init(&ec->primary_plane, ec, 0, 0);
        weston_compositor_stack_plane(ec, &ec->primary_plane, NULL);
 
        s = weston_config_get_section(ec->config, "keyboard", NULL, NULL);
index 5b813fc..73722b5 100644 (file)
@@ -505,6 +505,7 @@ struct weston_layer {
 };
 
 struct weston_plane {
+       struct weston_compositor *compositor;
        pixman_region32_t damage;
        pixman_region32_t clip;
        int32_t x, y;
@@ -961,7 +962,9 @@ void
 weston_layer_init(struct weston_layer *layer, struct wl_list *below);
 
 void
-weston_plane_init(struct weston_plane *plane, int32_t x, int32_t y);
+weston_plane_init(struct weston_plane *plane,
+                       struct weston_compositor *ec,
+                       int32_t x, int32_t y);
 void
 weston_plane_release(struct weston_plane *plane);