Re: [PATCH 5/9] compositor: Output unplug in clone mode
On Fri, 2014-02-14 at 09:56 +0200, Pekka Paalanen wrote: On Fri, 14 Feb 2014 15:17:40 +0800 Xiong Zhang xiong.y.zh...@intel.com wrote: Hi, just a general note: it seems the DRM backend code is getting into pretty deep indentation levels. I would recommend splitting chunks out into functions where you have a logical does-one-thing block, even if the function would be only used in one place. It makes the code flow easier to read, when the blocks have been chosen properly and the resulting functions have descriptive names. Only if possible, of course. Thanks for your recommendation. I will remember it and modify the code. thanks Thanks, pq ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH 5/9] compositor: Output unplug in clone mode
If unplugged output is a slave output, no need to restore views. If unplugged output is a master output which doesn't have slave output related it, views will be restored the same as extend mode. If unplugged output is a master output which have slave output related it, one slave output will be upgraded to master output, moving output following unplugged output isn't necessay, views on unplugged output will be marked as dirty. Signed-off-by: Xiong Zhang xiong.y.zh...@intel.com --- desktop-shell/shell.c | 13 ++- src/compositor-drm.c | 103 +++--- src/compositor.c | 15 ++-- src/compositor.h | 1 + 4 files changed, 122 insertions(+), 10 deletions(-) diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c index 1e4a255..85987e5 100644 --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -5600,6 +5600,9 @@ handle_output_destroy(struct wl_listener *listener, void *data) wl_list_remove(output_listener-role_change_listener.link); wl_list_remove(output_listener-link); free(output_listener); + + /* Trigger compositor repaint */ + weston_compositor_schedule_repaint(output_listener-output-compositor); } static void @@ -5676,10 +5679,18 @@ setup_output_destroy_handler(struct weston_compositor *ec, struct desktop_shell *shell) { struct weston_output *output; + struct weston_output *clone_output; wl_list_init(shell-output_list); - wl_list_for_each(output, ec-output_list, link) + wl_list_for_each(output, ec-output_list, link) { create_shell_output(shell, output); + if (!output-is_slave) { + wl_list_for_each(clone_output, +output-clone_output_list, +link) + create_shell_output(shell, clone_output); + } + } shell-output_create_listener.notify = handle_output_create; wl_signal_add(ec-output_created_signal, diff --git a/src/compositor-drm.c b/src/compositor-drm.c index 1d8c983..842710f 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -1217,6 +1217,8 @@ drm_assign_planes(struct weston_output *output) static void drm_output_fini_pixman(struct drm_output *output); +static void +drm_output_destroy_with_slave(struct drm_output *output); static void drm_output_destroy(struct weston_output *output_base) @@ -1259,6 +1261,15 @@ drm_output_destroy(struct weston_output *output_base) weston_plane_release(output-fb_plane); weston_plane_release(output-cursor_plane); + if (!output-base.is_slave + !wl_list_empty(output-base.clone_output_list)) { + drm_output_destroy_with_slave(output); + + /* One slave is upgraded to master, Don't move +* the following output.*/ + output_base.dont_move = 1; + } + weston_output_destroy(output-base); free(output); @@ -2420,6 +2431,73 @@ drm_output_add_slave(struct drm_compositor *ec) } } +/* The output with max width will be new_master. */ +static struct weston_output * +find_new_master(struct weston_output *master) +{ + struct weston_output *new_master, *output; + int32_t max_width = 0; + + new_master = NULL; + wl_list_for_each(output, master-clone_output_list, +link) { + if (output-current_mode-width max_width) { + max_width = output-current_mode-width; + new_master = output; + } + } + + return new_master; +} + +/* If a master is unplugged, a output will be chosen from + * master-clone_output_list to replace the unplugged master.*/ +static void +drm_output_destroy_with_slave(struct drm_output *output) +{ + struct weston_output *new_master, *tmp; + struct drm_output *clone_output, *next; + intoffset, move; + + new_master = find_new_master(output-base); + + /* When old master's width is different from new master's +* width, move the output following the old master. */ + offset = output-base.width - new_master-width; + if (offset != 0) { + move = 0; + wl_list_for_each(tmp, new_master-compositor-output_list, +link) { + if (move == 1) + weston_output_move(tmp, + tmp-x - offset, tmp-y); + + if (tmp == output-base) + move = 1; + } + } + + wl_list_remove(new_master-link); + wl_list_insert(output-base.link.prev, + new_master-link); + new_master-is_slave = 0; + + /* Link the remained clone output to new
Re: [PATCH 5/9] compositor: Output unplug in clone mode
On Fri, 14 Feb 2014 15:17:40 +0800 Xiong Zhang xiong.y.zh...@intel.com wrote: If unplugged output is a slave output, no need to restore views. If unplugged output is a master output which doesn't have slave output related it, views will be restored the same as extend mode. If unplugged output is a master output which have slave output related it, one slave output will be upgraded to master output, moving output following unplugged output isn't necessay, views on unplugged output will be marked as dirty. Signed-off-by: Xiong Zhang xiong.y.zh...@intel.com --- desktop-shell/shell.c | 13 ++- src/compositor-drm.c | 103 +++--- src/compositor.c | 15 ++-- src/compositor.h | 1 + 4 files changed, 122 insertions(+), 10 deletions(-) diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c index 1e4a255..85987e5 100644 --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -5600,6 +5600,9 @@ handle_output_destroy(struct wl_listener *listener, void *data) wl_list_remove(output_listener-role_change_listener.link); wl_list_remove(output_listener-link); free(output_listener); + + /* Trigger compositor repaint */ + weston_compositor_schedule_repaint(output_listener-output-compositor); } static void @@ -5676,10 +5679,18 @@ setup_output_destroy_handler(struct weston_compositor *ec, struct desktop_shell *shell) { struct weston_output *output; + struct weston_output *clone_output; wl_list_init(shell-output_list); - wl_list_for_each(output, ec-output_list, link) + wl_list_for_each(output, ec-output_list, link) { create_shell_output(shell, output); + if (!output-is_slave) { + wl_list_for_each(clone_output, + output-clone_output_list, + link) + create_shell_output(shell, clone_output); + } + } shell-output_create_listener.notify = handle_output_create; wl_signal_add(ec-output_created_signal, diff --git a/src/compositor-drm.c b/src/compositor-drm.c index 1d8c983..842710f 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -1217,6 +1217,8 @@ drm_assign_planes(struct weston_output *output) static void drm_output_fini_pixman(struct drm_output *output); +static void +drm_output_destroy_with_slave(struct drm_output *output); static void drm_output_destroy(struct weston_output *output_base) @@ -1259,6 +1261,15 @@ drm_output_destroy(struct weston_output *output_base) weston_plane_release(output-fb_plane); weston_plane_release(output-cursor_plane); + if (!output-base.is_slave + !wl_list_empty(output-base.clone_output_list)) { + drm_output_destroy_with_slave(output); + + /* One slave is upgraded to master, Don't move + * the following output.*/ + output_base.dont_move = 1; + } + weston_output_destroy(output-base); free(output); @@ -2420,6 +2431,73 @@ drm_output_add_slave(struct drm_compositor *ec) } } +/* The output with max width will be new_master. */ +static struct weston_output * +find_new_master(struct weston_output *master) +{ + struct weston_output *new_master, *output; + int32_t max_width = 0; + + new_master = NULL; + wl_list_for_each(output, master-clone_output_list, + link) { + if (output-current_mode-width max_width) { + max_width = output-current_mode-width; + new_master = output; + } + } + + return new_master; +} + +/* If a master is unplugged, a output will be chosen from + * master-clone_output_list to replace the unplugged master.*/ +static void +drm_output_destroy_with_slave(struct drm_output *output) +{ + struct weston_output *new_master, *tmp; + struct drm_output *clone_output, *next; + intoffset, move; + + new_master = find_new_master(output-base); + + /* When old master's width is different from new master's + * width, move the output following the old master. */ + offset = output-base.width - new_master-width; + if (offset != 0) { + move = 0; + wl_list_for_each(tmp, new_master-compositor-output_list, + link) { + if (move == 1) + weston_output_move(tmp, + tmp-x - offset, tmp-y); + + if (tmp == output-base) + move = 1; + } + } + + wl_list_remove(new_master-link); + wl_list_insert(output-base.link.prev, +