backend/wayland: Implement start() interface of ds_backend 67/278067/1
authorSeunghun Lee <shiin.lee@samsung.com>
Fri, 22 Apr 2022 00:17:57 +0000 (09:17 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Mon, 18 Jul 2022 05:08:23 +0000 (14:08 +0900)
The wayland backend defers creating new outputs until a user calls
ds_backend_start() even though a user requests creation of output before
ds_backend_start().

The wayland backend now emits a signal of new_output if a user calls
ds_backend_start(), which is for the behavior of ds_backend_start() to
be consistent regardless of the actual running backend.

Change-Id: If1748c7f591409c31b91438ba4ec561f7897e3fc

src/examples/tinyds.c
src/libds/backend/wayland/backend.c
src/libds/backend/wayland/backend.h
src/libds/backend/wayland/output.c

index 1c5ca4f..fcaabaf 100644 (file)
@@ -89,6 +89,7 @@ struct tinyds_server
 
     struct wl_list views;
 
+    struct wl_listener new_output;
     struct wl_listener new_input;
     struct wl_listener new_xdg_surface;
 };
@@ -115,7 +116,8 @@ static void server_fini(struct tinyds_server *server);
 static void server_add_view(struct tinyds_server *server,
         struct ds_xdg_surface *xdg_surface);
 static bool output_init(struct tinyds_output *output,
-        struct tinyds_server *server, int width, int height);
+        struct tinyds_server *server, struct ds_output *ds_output,
+        int width, int height);
 static void output_fini(struct tinyds_output *output);
 static void output_damage(struct tinyds_output *output);
 static void output_redraw(struct tinyds_output *output);
@@ -167,6 +169,18 @@ create_wl_backend(struct wl_display *display)
 }
 
 static void
+server_handle_new_output(struct wl_listener *listener, void *data)
+{
+    struct tinyds_server *server;
+    struct ds_output *ds_output = data;
+
+    server = wl_container_of(listener, server, new_output);
+
+    assert(output_init(&server->output, server, ds_output,
+            OUTPUT_WIDTH, OUTPUT_HEIGHT) == true);
+}
+
+static void
 keyboard_handle_device_destroy(struct wl_listener *listener, void *data)
 {
     struct tinyds_keyboard *kbd;
@@ -500,11 +514,13 @@ server_init(struct tinyds_server *server, struct wl_display *display)
     if (!server->backend)
         return false;
 
+    ds_wl_backend_create_output(server->backend);
+
     server->new_input.notify = server_handle_new_input;
     ds_backend_add_new_input_listener(server->backend, &server->new_input);
 
-    if (!output_init(&server->output, server, OUTPUT_WIDTH, OUTPUT_HEIGHT))
-        goto err;
+    server->new_output.notify = server_handle_new_output;
+    ds_backend_add_new_output_listener(server->backend, &server->new_output);
 
     server->compositor = ds_compositor_create(display);
     if (!server->compositor)
@@ -564,9 +580,10 @@ output_handle_frame(struct wl_listener *listener, void *data TINYDS_UNUSED)
 
 static bool
 output_init(struct tinyds_output *output, struct tinyds_server *server,
-        int width, int height)
+        struct ds_output *ds_output, int width, int height)
 {
     output->server = server;
+    output->ds_output = ds_output;
     output->width = width;
     output->height = height;
     output->drawable = true;
@@ -580,11 +597,6 @@ output_init(struct tinyds_output *output, struct tinyds_server *server,
     if (!output->swapchain)
         goto err_swapchain;
 
-    output->ds_output =
-        ds_wl_backend_create_output(server->backend);
-    if (!output->ds_output)
-        goto err_output;
-
     output->output_destroy.notify = output_handle_destroy;
     ds_output_add_destroy_listener(output->ds_output, &output->output_destroy);
 
@@ -593,8 +605,6 @@ output_init(struct tinyds_output *output, struct tinyds_server *server,
 
     return true;
 
-err_output:
-    ds_swapchain_destroy(output->swapchain);
 err_swapchain:
     ds_allocator_destroy(output->allocator);
 
@@ -604,8 +614,7 @@ err_swapchain:
 static void
 output_fini(struct tinyds_output *output)
 {
-    if (output->ds_output)
-        ds_output_destroy(output->ds_output);
+    ds_output_destroy(output->ds_output);
     ds_swapchain_destroy(output->swapchain);
     ds_allocator_destroy(output->allocator);
 }
index 3b5d6ab..5719e09 100644 (file)
@@ -81,6 +81,21 @@ wl_backend_from_backend(struct ds_backend *backend)
     return (struct ds_wl_backend *)backend;
 }
 
+static bool
+wl_backend_iface_start(struct ds_backend *ds_backend)
+{
+    struct ds_wl_backend *backend;
+
+    backend = wl_backend_from_backend(ds_backend);
+
+    ds_inf("Starting wayland backend");
+
+    for (size_t i = 0; i < backend->requested_outputs; i++)
+        create_wl_output(backend);
+
+    return true;
+}
+
 static void
 wl_backend_destroy(struct ds_wl_backend *backend)
 {
@@ -125,7 +140,7 @@ wl_backend_iface_destroy(struct ds_backend *backend)
 
 static const struct ds_backend_interface wl_backend_interface =
 {
-    .start = NULL,
+    .start = wl_backend_iface_start,
     .destroy = wl_backend_iface_destroy,
     .get_drm_fd = NULL,
 };
index 804fa22..12c8a27 100644 (file)
@@ -32,6 +32,8 @@ struct ds_wl_backend
 
     struct wl_event_source *server_event_source;
     struct ds_wl_backend_server server;
+
+    size_t requested_outputs;
 };
 
 struct ds_wl_buffer
@@ -122,6 +124,8 @@ struct ds_wl_touch
 struct ds_wl_backend *
 wl_backend_from_backend(struct ds_backend *backend);
 
+struct ds_wl_output *create_wl_output(struct ds_wl_backend *backend);
+
 void
 destroy_wl_buffer(struct ds_wl_buffer *buffer);
 
index 36ea5f7..c57820f 100644 (file)
@@ -23,6 +23,25 @@ ds_wl_backend_create_output(struct ds_backend *ds_backend)
 
     backend = wl_backend_from_backend(ds_backend);
 
+    if (!ds_backend->started) {
+        backend->requested_outputs++;
+        return NULL;
+    }
+
+    output = create_wl_output(backend);
+    if (!output) {
+        ds_err("Could not create ds_wl_output");
+        return NULL;
+    }
+
+    return &output->base;
+}
+
+struct ds_wl_output *
+create_wl_output(struct ds_wl_backend *backend)
+{
+    struct ds_wl_output *output;
+
     output = calloc(1, sizeof *output);
     if (!output) {
         ds_log_errno(DS_ERR, "Could not allocate ds_wl_output");
@@ -72,7 +91,7 @@ ds_wl_backend_create_output(struct ds_backend *ds_backend)
 
     ds_dbg("Wayland output(%p) created", output);
 
-    return &output->base;
+    return output;
 
 err:
     ds_output_destroy(&output->base);