From b43a012824af0165f3716c7986888213420885aa Mon Sep 17 00:00:00 2001 From: Marius Vlad Date: Thu, 6 Feb 2020 15:25:54 +0200 Subject: [PATCH] shell: Add a black surface in the fullscreen layer Now that we're capable of restarting the client shell without the need to restart the compositor, create a black surface and insert in the fullscreen layer as to denote that the client shell is no longer running. This black surface is removed when the 'ready' request is received and inserted back when the client shell unbinds from the agl-shell protocol. Also, we were missing implementation protocol specification as the presentation delay required a black surface being displayed instead, so this brings the implementation closer to that of the protocol specification. Bug-SPEC: SPEC-3161 Signed-off-by: Marius Vlad Change-Id: I40f01135583eea8af78d3077cdad97ad5ad450f5 --- src/ivi-compositor.h | 9 +++++ src/main.c | 2 + src/shell.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 112 insertions(+), 1 deletion(-) diff --git a/src/ivi-compositor.h b/src/ivi-compositor.h index 3d7bd25..5d210fb 100644 --- a/src/ivi-compositor.h +++ b/src/ivi-compositor.h @@ -103,6 +103,12 @@ struct ivi_output { struct ivi_surface *left; struct ivi_surface *right; + /* for the black surface */ + struct fullscreen_view { + struct ivi_surface *fs; + struct wl_listener fs_destroy; + } fullscreen_view; + struct wl_listener output_destroy; /* @@ -193,6 +199,9 @@ ivi_agl_systemd_notify(struct ivi_compositor *ivi) int ivi_shell_init(struct ivi_compositor *ivi); +void +ivi_shell_init_black_fs(struct ivi_compositor *ivi); + int ivi_shell_create_global(struct ivi_compositor *ivi); diff --git a/src/main.c b/src/main.c index 240fb77..54de038 100644 --- a/src/main.c +++ b/src/main.c @@ -1209,6 +1209,8 @@ int main(int argc, char *argv[]) weston_compositor_flush_heads_changed(ivi.compositor); + ivi_shell_init_black_fs(&ivi); + if (create_listening_socket(display, socket_name) < 0) goto error_compositor; diff --git a/src/shell.c b/src/shell.c index 6a1596e..16b4146 100644 --- a/src/shell.c +++ b/src/shell.c @@ -40,6 +40,12 @@ #include "agl-shell-server-protocol.h" +static void +create_black_surface_view(struct ivi_output *output); + +static void +insert_black_surface(struct ivi_output *output); + void ivi_set_desktop_surface(struct ivi_surface *surface) { @@ -49,6 +55,17 @@ ivi_set_desktop_surface(struct ivi_surface *surface) wl_list_insert(&surface->ivi->surfaces, &surface->link); } +void +ivi_shell_init_black_fs(struct ivi_compositor *ivi) +{ + struct ivi_output *out; + + wl_list_for_each(out, &ivi->outputs, link) { + create_black_surface_view(out); + insert_black_surface(out); + } +} + int ivi_shell_init(struct ivi_compositor *ivi) { @@ -167,6 +184,87 @@ ivi_launch_shell_client(struct ivi_compositor *ivi) return 0; } +static void +destroy_black_view(struct wl_listener *listener, void *data) +{ + struct fullscreen_view *fs = + wl_container_of(listener, fs, fs_destroy); + + + if (fs && fs->fs) { + if (fs->fs->view && fs->fs->view->surface) { + weston_surface_destroy(fs->fs->view->surface); + fs->fs->view = NULL; + } + + free(fs->fs); + wl_list_remove(&fs->fs_destroy.link); + } +} + + +static void +create_black_surface_view(struct ivi_output *output) +{ + struct weston_surface *surface = NULL; + struct weston_view *view; + struct ivi_compositor *ivi = output->ivi; + struct weston_compositor *wc= ivi->compositor; + struct weston_output *woutput = output->output; + + surface = weston_surface_create(wc); + view = weston_view_create(surface); + + assert(view || surface); + + weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1); + weston_surface_set_size(surface, woutput->width, woutput->height); + weston_view_set_position(view, woutput->x, woutput->y); + + output->fullscreen_view.fs = zalloc(sizeof(struct ivi_surface)); + output->fullscreen_view.fs->view = view; + + output->fullscreen_view.fs_destroy.notify = destroy_black_view; + wl_signal_add(&woutput->destroy_signal, + &output->fullscreen_view.fs_destroy); +} + +static void +remove_black_surface(struct ivi_output *output) +{ + struct weston_view *view = output->fullscreen_view.fs->view; + + assert(view->is_mapped == true || + view->surface->is_mapped == true); + + view->is_mapped = false; + view->surface->is_mapped = false; + + weston_layer_entry_remove(&view->layer_link); + weston_view_update_transform(view); + + weston_output_damage(output->output); +} + +static void +insert_black_surface(struct ivi_output *output) +{ + struct weston_view *view = output->fullscreen_view.fs->view; + + if (view->is_mapped || view->surface->is_mapped) + return; + + weston_layer_entry_remove(&view->layer_link); + weston_layer_entry_insert(&output->ivi->fullscreen.view_list, + &view->layer_link); + + view->is_mapped = true; + view->surface->is_mapped = true; + + weston_view_update_transform(view); + weston_output_damage(output->output); +} + static void shell_ready(struct wl_client *client, struct wl_resource *shell_res) { @@ -179,9 +277,9 @@ shell_ready(struct wl_client *client, struct wl_resource *shell_res) return; ivi->shell_client.ready = true; - /* TODO: Create a black screen and remove it here */ wl_list_for_each(output, &ivi->outputs, link) { + remove_black_surface(output); ivi_layout_init(ivi, output); } @@ -373,6 +471,8 @@ unbind_agl_shell(struct wl_resource *resource) weston_layer_entry_remove(&output->active->view->layer_link); output->active = NULL; } + + insert_black_surface(output); } wl_list_for_each_safe(surf, surf_tmp, &ivi->surfaces, link) { -- 2.16.6