In drm backend, the cursor_surface->plane point to drm_output->cursor_plane. when this output is removed, drm_output->cursor_plane is destroyed, but cursor_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 occure in weston_surface_damage_below() function.
Eech client APP has its own cursor surface, if mouse focus isn't on this app's cursor surface, this app's cursor surface won't be on any cursor_layer and compositor->surface_list.But once moving mouse to this APP, this APP's cursor surface will be in compositor->surface_list. In order to track these hiden cursor surface,plane should track all the surfaces belonged to it, when plane is destroyed, all surface's plane on destroyed plane is set to NULL. bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=69777 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) Signed-off-by: Xiong Zhang <xiong.y.zh...@intel.com> --- src/compositor.c | 22 +++++++++++++++++++--- src/compositor.h | 2 ++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/compositor.c b/src/compositor.c index 376ddfd..990a378 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -362,6 +362,7 @@ weston_surface_create(struct weston_compositor *compositor) wl_list_init(&surface->link); wl_list_init(&surface->layer_link); + wl_list_init(&surface->plane_link); surface->compositor = compositor; surface->alpha = 1.0; @@ -377,7 +378,7 @@ weston_surface_create(struct weston_compositor *compositor) surface->pending.buffer_transform = surface->buffer_transform; surface->pending.buffer_scale = surface->buffer_scale; surface->output = NULL; - surface->plane = &compositor->primary_plane; + surface->plane = NULL; surface->pending.newly_attached = 0; pixman_region32_init(&surface->damage); @@ -566,7 +567,10 @@ weston_surface_move_to_plane(struct weston_surface *surface, return; weston_surface_damage_below(surface); + if (surface->plane) + wl_list_remove(&surface->plane_link); surface->plane = plane; + wl_list_insert(plane->surface_list.prev, &surface->plane_link); weston_surface_damage(surface); } @@ -578,8 +582,9 @@ weston_surface_damage_below(struct weston_surface *surface) pixman_region32_init(&damage); pixman_region32_subtract(&damage, &surface->transform.boundingbox, &surface->clip); - pixman_region32_union(&surface->plane->damage, - &surface->plane->damage, &damage); + if (surface->plane) + pixman_region32_union(&surface->plane->damage, + &surface->plane->damage, &damage); pixman_region32_fini(&damage); } @@ -1125,6 +1130,9 @@ weston_surface_destroy(struct weston_surface *surface) weston_surface_set_transform_parent(surface, NULL); + if (surface->plane) + wl_list_remove(&surface->plane_link); + free(surface); } @@ -2614,14 +2622,22 @@ weston_plane_init(struct weston_plane *plane, int32_t x, int32_t y) /* Init the link so that the call to wl_list_remove() when releasing * the plane without ever stacking doesn't lead to a crash */ wl_list_init(&plane->link); + wl_list_init(&plane->surface_list); } WL_EXPORT void weston_plane_release(struct weston_plane *plane) { + struct weston_surface *surface, *next; + pixman_region32_fini(&plane->damage); pixman_region32_fini(&plane->clip); + wl_list_for_each_safe(surface, next, &plane->surface_list, plane_link) { + wl_list_remove(&surface->plane_link); + surface->plane = NULL; + } + wl_list_remove(&plane->link); } diff --git a/src/compositor.h b/src/compositor.h index a19d966..bb00c79 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -508,6 +508,7 @@ struct weston_plane { pixman_region32_t damage; pixman_region32_t clip; int32_t x, y; + struct wl_list surface_list; struct wl_list link; }; @@ -724,6 +725,7 @@ struct weston_surface { pixman_region32_t input; struct wl_list link; struct wl_list layer_link; + struct wl_list plane_link; float alpha; /* part of geometry, see below */ struct weston_plane *plane; int32_t ref_count; -- 1.8.3.2 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel