From 0f690daf0d548cc45918c9ab6b882ef2ac208324 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Thu, 3 Mar 2022 18:03:25 +0900 Subject: [PATCH 01/16] examples: Use output mode instead of arbitrary size Change-Id: I973e052a2a32eb3fc62c02014af4e2cb3ede1380 --- src/examples/tinyds-tdm.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/examples/tinyds-tdm.c b/src/examples/tinyds-tdm.c index 4207fb1..3841b84 100644 --- a/src/examples/tinyds-tdm.c +++ b/src/examples/tinyds-tdm.c @@ -22,9 +22,6 @@ #define TINYDS_UNUSED __attribute__((unused)) -#define OUTPUT_WIDTH 1280 -#define OUTPUT_HEIGHT 720 - struct tinyds_output { struct tinyds_server *server; @@ -223,6 +220,7 @@ backend_handle_new_output(struct wl_listener *listener, void *data) struct tinyds_server *server; struct tinyds_output *output; struct ds_output *ds_output; + const struct ds_output_mode *mode; server = wl_container_of(listener, server, new_output); ds_output = data; @@ -232,6 +230,9 @@ backend_handle_new_output(struct wl_listener *listener, void *data) if (server->output) return; + mode = ds_output_preferred_mode(ds_output); + ds_output_set_mode(ds_output, mode); + output = calloc(1, sizeof *output); if (!output) return; @@ -243,7 +244,7 @@ backend_handle_new_output(struct wl_listener *listener, void *data) } output->swapchain = ds_swapchain_create(output->allocator, - OUTPUT_WIDTH, OUTPUT_HEIGHT, DRM_FORMAT_XRGB8888); // FIXME output mode + mode->width, mode->height, DRM_FORMAT_XRGB8888); if (!output->swapchain) { ds_allocator_destroy(output->allocator); free(output); -- 2.7.4 From acbc20274fac4b99a7784f43612bbe1f0446f513 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Thu, 3 Mar 2022 19:01:28 +0900 Subject: [PATCH 02/16] backend/tdm: Get buffer only if it's necessary Change-Id: I8c4fcc67b316c5eae0c11ad817632319d17fb2aa --- src/libds/backend/tdm/output.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libds/backend/tdm/output.c b/src/libds/backend/tdm/output.c index 06edbf6..a67c618 100644 --- a/src/libds/backend/tdm/output.c +++ b/src/libds/backend/tdm/output.c @@ -196,16 +196,16 @@ tdm_output_iface_commit(struct ds_output *ds_output) } } - ds_buffer = ds_output->pending.buffer; - buffer = get_or_create_tdm_buffer(output->backend, ds_buffer); - if (!buffer) - return false; - if (ds_output->pending.committed & DS_OUTPUT_STATE_BUFFER) { tdm_region fb_damage; tdm_error err; uint32_t num_changes; + ds_buffer = ds_output->pending.buffer; + buffer = get_or_create_tdm_buffer(output->backend, ds_buffer); + if (!buffer) + return false; + memset(&fb_damage, 0, sizeof(fb_damage)); err = tdm_hwc_set_client_target_buffer(output->tdm.hwc, buffer->surface, fb_damage); -- 2.7.4 From b4b30a2f00d8058829bfd8e4e8177cacc445833d Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Thu, 3 Mar 2022 19:03:50 +0900 Subject: [PATCH 03/16] output: Rename function more explicitly Change-Id: I58c743aafd6c9b610056391ff9f4ac69e9d90f54 --- include/libds/output.h | 2 +- src/examples/tinyds-tdm.c | 2 +- src/libds/output.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/libds/output.h b/include/libds/output.h index 35fee14..c7ee476 100644 --- a/include/libds/output.h +++ b/include/libds/output.h @@ -27,7 +27,7 @@ void ds_output_attach_buffer(struct ds_output *output, struct ds_buffer *buffer); const struct ds_output_mode * -ds_output_preferred_mode(struct ds_output *output); +ds_output_get_preferred_mode(struct ds_output *output); void ds_output_set_mode(struct ds_output *output, diff --git a/src/examples/tinyds-tdm.c b/src/examples/tinyds-tdm.c index 3841b84..2c91a66 100644 --- a/src/examples/tinyds-tdm.c +++ b/src/examples/tinyds-tdm.c @@ -230,7 +230,7 @@ backend_handle_new_output(struct wl_listener *listener, void *data) if (server->output) return; - mode = ds_output_preferred_mode(ds_output); + mode = ds_output_get_preferred_mode(ds_output); ds_output_set_mode(ds_output, mode); output = calloc(1, sizeof *output); diff --git a/src/libds/output.c b/src/libds/output.c index f5cd356..4f67056 100644 --- a/src/libds/output.c +++ b/src/libds/output.c @@ -68,7 +68,7 @@ ds_output_attach_buffer(struct ds_output *output, struct ds_buffer *buffer) } WL_EXPORT const struct ds_output_mode * -ds_output_preferred_mode(struct ds_output *output) +ds_output_get_preferred_mode(struct ds_output *output) { struct ds_output_mode *mode; -- 2.7.4 From 694d3c7f46f8db5ba68751e684c6a940a3ed1780 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Fri, 4 Mar 2022 10:44:57 +0900 Subject: [PATCH 04/16] backend/tdm: Split commit function into small functions No functional changes. It improves readability. Change-Id: I0b95360f5dc54e7023ab3f54c3b9cf2057a82686 --- src/libds/backend/tdm/output.c | 135 ++++++++++++++++++++++++----------------- 1 file changed, 79 insertions(+), 56 deletions(-) diff --git a/src/libds/backend/tdm/output.c b/src/libds/backend/tdm/output.c index a67c618..bc931d7 100644 --- a/src/libds/backend/tdm/output.c +++ b/src/libds/backend/tdm/output.c @@ -11,6 +11,9 @@ static bool tdm_output_init_modes(struct ds_tdm_output *output); static void tdm_output_destroy(struct ds_tdm_output *output); static void tdm_output_init_hwc(struct ds_tdm_output *output); static bool tdm_output_update_mode(struct ds_tdm_output *output); +static bool tdm_output_set_pending_fb(struct ds_tdm_output *output, + struct ds_buffer *ds_buffer); +static bool tdm_output_hwc_commit(struct ds_tdm_output *output); struct ds_tdm_output * create_tdm_output(struct ds_tdm_backend *tdm, tdm_output *tdm_output) @@ -167,25 +170,10 @@ tdm_output_attach_back_buffer(struct ds_tdm_output *output, output->back_buffer = buffer; } -static void -tdm_output_hwc_commit_handler(tdm_hwc *hwc, unsigned int sequence, - unsigned int tv_sec, unsigned int tv_usec, void *user_data) -{ - struct ds_tdm_output *output; - - output = user_data; - - tdm_output_update_front_buffer(output); - - wl_signal_emit(&output->base.events.frame, &output->base); -} - static bool tdm_output_iface_commit(struct ds_output *ds_output) { struct ds_tdm_output *output; - struct ds_tdm_buffer *buffer; - struct ds_buffer *ds_buffer; output = tdm_output_from_output(ds_output); @@ -197,51 +185,19 @@ tdm_output_iface_commit(struct ds_output *ds_output) } if (ds_output->pending.committed & DS_OUTPUT_STATE_BUFFER) { - tdm_region fb_damage; - tdm_error err; - uint32_t num_changes; - - ds_buffer = ds_output->pending.buffer; - buffer = get_or_create_tdm_buffer(output->backend, ds_buffer); - if (!buffer) - return false; - - memset(&fb_damage, 0, sizeof(fb_damage)); - err = tdm_hwc_set_client_target_buffer(output->tdm.hwc, - buffer->surface, fb_damage); - if (err != TDM_ERROR_NONE) { - ds_err("Could not set hwc client target buffer"); - ds_buffer_unlock(buffer->buffer); - return false; - } - - err = tdm_hwc_validate(output->tdm.hwc, NULL, 0, &num_changes); - if (err != TDM_ERROR_NONE) { - ds_err("Could not hwc validate"); - ds_buffer_unlock(buffer->buffer); - return false; - } - - err = tdm_hwc_accept_validation(output->tdm.hwc); - if (err != TDM_ERROR_NONE) { - ds_err("Could not hwc accept validation"); - ds_buffer_unlock(buffer->buffer); - return false; - } + if (!tdm_output_set_pending_fb(output, ds_output->pending.buffer)) + ds_err("Could not update buffer"); + } - err = tdm_hwc_commit(output->tdm.hwc, 0, tdm_output_hwc_commit_handler, - output); - if (err != TDM_ERROR_NONE) { - ds_err("Could not hwc commit"); - ds_buffer_unlock(buffer->buffer); - return false; + if (!tdm_output_hwc_commit(output)) { + ds_err("Could not commit tdm output"); + if (output->back_buffer) { + tdm_buffer_release(output->back_buffer); } - - tdm_output_attach_back_buffer(output, buffer); - - ds_dbg("Swap Buffer!!!!!"); } + ds_dbg("Swap Buffer!!!!!"); + return true; } @@ -346,3 +302,70 @@ tdm_output_update_mode(struct ds_tdm_output *output) return true; } + +static bool +tdm_output_set_pending_fb(struct ds_tdm_output *output, + struct ds_buffer *ds_buffer) +{ + struct ds_tdm_buffer *buffer; + tdm_region fb_damage; + tdm_error err; + + buffer = get_or_create_tdm_buffer(output->backend, ds_buffer); + if (!buffer) + return false; + + memset(&fb_damage, 0, sizeof(fb_damage)); + err = tdm_hwc_set_client_target_buffer(output->tdm.hwc, + buffer->surface, fb_damage); + if (err != TDM_ERROR_NONE) { + ds_err("Could not set hwc client target buffer"); + ds_buffer_unlock(buffer->buffer); + return false; + } + + tdm_output_attach_back_buffer(output, buffer); + + return true; +} + +static void +tdm_output_hwc_commit_handler(tdm_hwc *hwc, unsigned int sequence, + unsigned int tv_sec, unsigned int tv_usec, void *user_data) +{ + struct ds_tdm_output *output; + + output = user_data; + + tdm_output_update_front_buffer(output); + + wl_signal_emit(&output->base.events.frame, &output->base); +} + +static bool +tdm_output_hwc_commit(struct ds_tdm_output *output) +{ + tdm_error err; + uint32_t num_changes; + + err = tdm_hwc_validate(output->tdm.hwc, NULL, 0, &num_changes); + if (err != TDM_ERROR_NONE) { + ds_err("Could not hwc validate"); + return false; + } + + err = tdm_hwc_accept_validation(output->tdm.hwc); + if (err != TDM_ERROR_NONE) { + ds_err("Could not hwc accept validation"); + return false; + } + + err = tdm_hwc_commit(output->tdm.hwc, 0, tdm_output_hwc_commit_handler, + output); + if (err != TDM_ERROR_NONE) { + ds_err("Could not hwc commit"); + return false; + } + + return true; +} -- 2.7.4 From b23208728cbed66e2d6b73723d06cdfa312358b2 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Fri, 4 Mar 2022 10:49:50 +0900 Subject: [PATCH 05/16] backend/tdm: Remove prefix tdm from static functions It's to avoid confusion with tdm api. For static functions, the names chosen aren't as important. Change-Id: I8e952eac5dfdba304896a8f3d7f6a56f9ed00332 --- src/libds/backend/tdm/output.c | 56 +++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/libds/backend/tdm/output.c b/src/libds/backend/tdm/output.c index bc931d7..a05d2c9 100644 --- a/src/libds/backend/tdm/output.c +++ b/src/libds/backend/tdm/output.c @@ -7,13 +7,13 @@ #include static const struct ds_output_interface tdm_output_iface; -static bool tdm_output_init_modes(struct ds_tdm_output *output); -static void tdm_output_destroy(struct ds_tdm_output *output); -static void tdm_output_init_hwc(struct ds_tdm_output *output); -static bool tdm_output_update_mode(struct ds_tdm_output *output); -static bool tdm_output_set_pending_fb(struct ds_tdm_output *output, +static bool output_init_modes(struct ds_tdm_output *output); +static void output_destroy(struct ds_tdm_output *output); +static void output_init_hwc(struct ds_tdm_output *output); +static bool output_update_mode(struct ds_tdm_output *output); +static bool output_set_pending_fb(struct ds_tdm_output *output, struct ds_buffer *ds_buffer); -static bool tdm_output_hwc_commit(struct ds_tdm_output *output); +static bool output_hwc_commit(struct ds_tdm_output *output); struct ds_tdm_output * create_tdm_output(struct ds_tdm_backend *tdm, tdm_output *tdm_output) @@ -42,7 +42,7 @@ create_tdm_output(struct ds_tdm_backend *tdm, tdm_output *tdm_output) if (conn == TDM_OUTPUT_CONN_STATUS_CONNECTED) { output->status = DS_TDM_OUTPUT_CONNECTED; - if (!tdm_output_init_modes(output)) { + if (!output_init_modes(output)) { ds_err("Could not initialize modes of tdm output(%p)", tdm_output); goto err_status; @@ -53,7 +53,7 @@ create_tdm_output(struct ds_tdm_backend *tdm, tdm_output *tdm_output) } if (tdm_output_get_hwc(output->tdm.output, NULL) != NULL) - tdm_output_init_hwc(output); + output_init_hwc(output); ds_inf("TDM output(%p) created: hwc(%p)", output, output->tdm.hwc); @@ -73,12 +73,12 @@ tdm_output_from_output(struct ds_output *ds_output) } static void -tdm_output_iface_destroy(struct ds_output *ds_output) +output_iface_destroy(struct ds_output *ds_output) { struct ds_tdm_output *output; output = tdm_output_from_output(ds_output); - tdm_output_destroy(output); + output_destroy(output); } void @@ -153,7 +153,7 @@ tdm_buffer_release(struct ds_tdm_buffer *buffer) } static void -tdm_output_update_front_buffer(struct ds_tdm_output *output) +output_update_front_buffer(struct ds_tdm_output *output) { if (output->front_buffer) tdm_buffer_release(output->front_buffer); @@ -162,7 +162,7 @@ tdm_output_update_front_buffer(struct ds_tdm_output *output) } static void -tdm_output_attach_back_buffer(struct ds_tdm_output *output, +output_attach_back_buffer(struct ds_tdm_output *output, struct ds_tdm_buffer *buffer) { if (output->back_buffer) @@ -171,25 +171,25 @@ tdm_output_attach_back_buffer(struct ds_tdm_output *output, } static bool -tdm_output_iface_commit(struct ds_output *ds_output) +output_iface_commit(struct ds_output *ds_output) { struct ds_tdm_output *output; output = tdm_output_from_output(ds_output); if (ds_output->pending.committed & DS_OUTPUT_STATE_MODE) { - if (!tdm_output_update_mode(output)) { + if (!output_update_mode(output)) { ds_err("Could not update TDM mode"); return false; } } if (ds_output->pending.committed & DS_OUTPUT_STATE_BUFFER) { - if (!tdm_output_set_pending_fb(output, ds_output->pending.buffer)) + if (!output_set_pending_fb(output, ds_output->pending.buffer)) ds_err("Could not update buffer"); } - if (!tdm_output_hwc_commit(output)) { + if (!output_hwc_commit(output)) { ds_err("Could not commit tdm output"); if (output->back_buffer) { tdm_buffer_release(output->back_buffer); @@ -203,12 +203,12 @@ tdm_output_iface_commit(struct ds_output *ds_output) static const struct ds_output_interface tdm_output_iface = { - .destroy = tdm_output_iface_destroy, - .commit = tdm_output_iface_commit, + .destroy = output_iface_destroy, + .commit = output_iface_commit, }; static void -tdm_output_destroy(struct ds_tdm_output *output) +output_destroy(struct ds_tdm_output *output) { struct ds_tdm_output_mode *mode, *mode_tmp; @@ -227,7 +227,7 @@ tdm_output_destroy(struct ds_tdm_output *output) } static bool -tdm_output_init_modes(struct ds_tdm_output *output) +output_init_modes(struct ds_tdm_output *output) { struct ds_tdm_output_mode *mode; const tdm_output_mode *tdm_modes, *tdm_mode; @@ -274,7 +274,7 @@ tdm_output_init_modes(struct ds_tdm_output *output) } static void -tdm_output_init_hwc(struct ds_tdm_output *output) +output_init_hwc(struct ds_tdm_output *output) { tdm_error err; @@ -286,7 +286,7 @@ tdm_output_init_hwc(struct ds_tdm_output *output) } static bool -tdm_output_update_mode(struct ds_tdm_output *output) +output_update_mode(struct ds_tdm_output *output) { const struct ds_tdm_output_mode *mode; tdm_error err; @@ -304,7 +304,7 @@ tdm_output_update_mode(struct ds_tdm_output *output) } static bool -tdm_output_set_pending_fb(struct ds_tdm_output *output, +output_set_pending_fb(struct ds_tdm_output *output, struct ds_buffer *ds_buffer) { struct ds_tdm_buffer *buffer; @@ -324,26 +324,26 @@ tdm_output_set_pending_fb(struct ds_tdm_output *output, return false; } - tdm_output_attach_back_buffer(output, buffer); + output_attach_back_buffer(output, buffer); return true; } static void -tdm_output_hwc_commit_handler(tdm_hwc *hwc, unsigned int sequence, +output_hwc_commit_handler(tdm_hwc *hwc, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data) { struct ds_tdm_output *output; output = user_data; - tdm_output_update_front_buffer(output); + output_update_front_buffer(output); wl_signal_emit(&output->base.events.frame, &output->base); } static bool -tdm_output_hwc_commit(struct ds_tdm_output *output) +output_hwc_commit(struct ds_tdm_output *output) { tdm_error err; uint32_t num_changes; @@ -360,7 +360,7 @@ tdm_output_hwc_commit(struct ds_tdm_output *output) return false; } - err = tdm_hwc_commit(output->tdm.hwc, 0, tdm_output_hwc_commit_handler, + err = tdm_hwc_commit(output->tdm.hwc, 0, output_hwc_commit_handler, output); if (err != TDM_ERROR_NONE) { ds_err("Could not hwc commit"); -- 2.7.4 From dae411b8d2119814013630cc9bd1f22302594394 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Fri, 4 Mar 2022 14:25:20 +0900 Subject: [PATCH 06/16] Fix formatting Change-Id: I5df4c04cbd50c3f7b4065dfd5b9084f3919c3d3e --- src/libds/allocator.c | 1 + src/libds/allocator/shm.c | 9 ++++++--- src/libds/allocator/tbm.c | 6 +++--- src/libds/backend.c | 4 +++- src/libds/backend/tdm/backend.c | 14 ++++++------- src/libds/backend/tdm/output.c | 13 ++++++------ src/libds/backend/tdm/tdm.h | 1 + src/libds/backend/wayland/backend.c | 17 ++++++++-------- src/libds/backend/wayland/output.c | 11 ++++++---- src/libds/buffer.c | 12 ++++++----- src/libds/client_buffer.h | 3 ++- src/libds/client_buffer/shm_client_buffer.c | 11 ++++++---- src/libds/compositor.c | 12 +++++++---- src/libds/log.c | 9 +++++++-- src/libds/pixel_format.c | 1 + src/libds/presentation.c | 7 ++++--- src/libds/region.c | 9 +++++---- src/libds/subcompositor.c | 11 ++++++---- src/libds/surface/subsurface.c | 7 +++++-- src/libds/surface/surface-private.h | 1 + src/libds/surface/surface.c | 31 +++++++++++++++++++---------- src/libds/swapchain.c | 2 +- src/libds/util/time.c | 4 +++- src/libds/xdg_shell/xdg_shell.c | 17 ++++++++-------- src/libds/xdg_shell/xdg_shell.h | 2 +- src/libds/xdg_shell/xdg_surface.c | 4 +++- src/libds/xdg_shell/xdg_toplevel.c | 14 +++++++------ 27 files changed, 142 insertions(+), 91 deletions(-) diff --git a/src/libds/allocator.c b/src/libds/allocator.c index 34c0aa7..c9769be 100644 --- a/src/libds/allocator.c +++ b/src/libds/allocator.c @@ -1,5 +1,6 @@ #include #include + #include #include "libds/log.h" diff --git a/src/libds/allocator/shm.c b/src/libds/allocator/shm.c index a0acd0c..3fad474 100644 --- a/src/libds/allocator/shm.c +++ b/src/libds/allocator/shm.c @@ -2,6 +2,7 @@ #include #include #include + #include #include @@ -127,6 +128,7 @@ shm_allocator_create_buffer(struct ds_allocator *ds_allocator, int width, int height, uint32_t format) { struct ds_shm_buffer *buffer; + int bytes_per_pixel, stride; buffer = calloc(1, sizeof *buffer); if (!buffer) @@ -135,8 +137,8 @@ shm_allocator_create_buffer(struct ds_allocator *ds_allocator, ds_buffer_init(&buffer->base, &shm_buffer_interface, width, height); // FIXME - int bytes_per_pixel = 4; - int stride = width * bytes_per_pixel; + bytes_per_pixel = 4; + stride = width * bytes_per_pixel; buffer->size = stride * height; buffer->shm.fd = allocate_shm_file(buffer->size); if (buffer->shm.fd < 0) { @@ -164,7 +166,8 @@ shm_allocator_create_buffer(struct ds_allocator *ds_allocator, return &buffer->base; } -static const struct ds_allocator_interface shm_allocator_iface = { +static const struct ds_allocator_interface shm_allocator_iface = +{ .destroy = shm_allocator_destroy, .create_buffer = shm_allocator_create_buffer, }; diff --git a/src/libds/allocator/tbm.c b/src/libds/allocator/tbm.c index f4d0702..dc3be42 100644 --- a/src/libds/allocator/tbm.c +++ b/src/libds/allocator/tbm.c @@ -1,8 +1,8 @@ #include #include + #include #include - #include #include @@ -136,7 +136,6 @@ static const struct ds_buffer_interface tbm_buffer_iface = .end_data_ptr_access = tbm_buffer_end_data_ptr_access, }; - static void tbm_allocator_destroy(struct ds_allocator *ds_allocator) { @@ -171,7 +170,8 @@ tbm_allocator_create_buffer(struct ds_allocator *ds_allocator, return &buffer->base; } -static const struct ds_allocator_interface tbm_allocator_iface = { +static const struct ds_allocator_interface tbm_allocator_iface = +{ .destroy = tbm_allocator_destroy, .create_buffer = tbm_allocator_create_buffer, }; diff --git a/src/libds/backend.c b/src/libds/backend.c index d52a8d2..ee2a912 100644 --- a/src/libds/backend.c +++ b/src/libds/backend.c @@ -1,4 +1,5 @@ #include + #include #include "libds/interfaces/backend.h" @@ -41,7 +42,8 @@ ds_backend_add_new_output_listener(struct ds_backend *backend, } void -ds_backend_init(struct ds_backend *backend, const struct ds_backend_interface *iface) +ds_backend_init(struct ds_backend *backend, + const struct ds_backend_interface *iface) { backend->iface = iface; wl_signal_init(&backend->events.destroy); diff --git a/src/libds/backend/tdm/backend.c b/src/libds/backend/tdm/backend.c index c893702..e756ac1 100644 --- a/src/libds/backend/tdm/backend.c +++ b/src/libds/backend/tdm/backend.c @@ -2,9 +2,11 @@ #include #include "libds/log.h" + #include "tdm.h" static const struct ds_backend_interface tdm_backend_iface; + static void tdm_backend_handle_display_destroy(struct wl_listener *listener, void *data); static void tdm_backend_destroy(struct ds_tdm_backend *tdm); @@ -79,13 +81,11 @@ tdm_backend_destroy(struct ds_tdm_backend *tdm) struct ds_tdm_output *output, *tmp_output; struct ds_tdm_buffer *buffer, *tmp_buffer; - wl_list_for_each_safe(output, tmp_output, &tdm->outputs, link) { + wl_list_for_each_safe(output, tmp_output, &tdm->outputs, link) ds_output_destroy(&output->base); - } - wl_list_for_each_safe(buffer, tmp_buffer, &tdm->buffers, link) { + wl_list_for_each_safe(buffer, tmp_buffer, &tdm->buffers, link) destroy_tdm_buffer(buffer); - } wl_list_remove(&tdm->display_destroy.link); wl_event_source_remove(tdm->tdm_event); @@ -149,7 +149,8 @@ tdm_backend_iface_destroy(struct ds_backend *backend) tdm_backend_destroy(tdm); } -static const struct ds_backend_interface tdm_backend_iface = { +static const struct ds_backend_interface tdm_backend_iface = +{ .start = tdm_backend_iface_start, .destroy = tdm_backend_iface_destroy, .get_drm_fd = NULL, @@ -167,9 +168,8 @@ tdm_backend_handle_display_destroy(struct wl_listener *listener, void *data) static int tdm_backend_handle_tdm_event(int fd, uint32_t mask, void *data) { - struct ds_tdm_backend *tdm; + struct ds_tdm_backend *tdm = data; - tdm = data; tdm_display_handle_events(tdm->tdm_display); return 0; diff --git a/src/libds/backend/tdm/output.c b/src/libds/backend/tdm/output.c index a05d2c9..958b8ce 100644 --- a/src/libds/backend/tdm/output.c +++ b/src/libds/backend/tdm/output.c @@ -1,10 +1,12 @@ #include #include +#include + #include "libds/log.h" #include "libds/allocator/tbm.h" + #include "tdm.h" -#include static const struct ds_output_interface tdm_output_iface; static bool output_init_modes(struct ds_tdm_output *output); @@ -114,9 +116,8 @@ create_tdm_buffer(struct ds_tdm_backend *backend, struct ds_buffer *ds_buffer) } buffer = calloc(1, sizeof *buffer); - if (!buffer) { + if (!buffer) return NULL; - } buffer->surface = surface; buffer->buffer = ds_buffer_lock(ds_buffer); @@ -241,7 +242,7 @@ output_init_modes(struct ds_tdm_output *output) return false; } - ds_inf("Detected modes:"); + ds_dbg("Detected modes:"); for (i = 0; i < num_modes; i++) { tdm_mode = &tdm_modes[i]; @@ -333,9 +334,7 @@ static void output_hwc_commit_handler(tdm_hwc *hwc, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data) { - struct ds_tdm_output *output; - - output = user_data; + struct ds_tdm_output *output = user_data; output_update_front_buffer(output); diff --git a/src/libds/backend/tdm/tdm.h b/src/libds/backend/tdm/tdm.h index 2b1c1e4..1c80ef9 100644 --- a/src/libds/backend/tdm/tdm.h +++ b/src/libds/backend/tdm/tdm.h @@ -2,6 +2,7 @@ #define DS_BACKEND_TDM_H #include + #include #include "libds/interfaces/backend.h" diff --git a/src/libds/backend/wayland/backend.c b/src/libds/backend/wayland/backend.c index 9b6cd3a..778ca1c 100644 --- a/src/libds/backend/wayland/backend.c +++ b/src/libds/backend/wayland/backend.c @@ -1,15 +1,16 @@ #include #include #include + #include #include -#include "backend.h" #include "libds/log.h" #include "libds/output.h" - #include "xdg-shell-client-protocol.h" +#include "backend.h" + static const struct ds_backend_interface wl_backend_interface; static void wl_backend_handle_display_destroy(struct wl_listener *listener, void *data); @@ -86,13 +87,11 @@ wl_backend_destroy(struct ds_wl_backend *backend) ds_dbg("Destroy wayland backend(%p)", backend); - wl_list_for_each_safe(output, tmp_output, &backend->outputs, link) { + wl_list_for_each_safe(output, tmp_output, &backend->outputs, link) ds_output_destroy(&output->base); - } - wl_list_for_each_safe(buffer, tmp_buffer, &backend->buffers, link) { + wl_list_for_each_safe(buffer, tmp_buffer, &backend->buffers, link) destroy_wl_buffer(buffer); - } ds_backend_finish(&backend->base); @@ -118,7 +117,8 @@ wl_backend_iface_destroy(struct ds_backend *backend) wl_backend_destroy(wl_backend); } -static const struct ds_backend_interface wl_backend_interface = { +static const struct ds_backend_interface wl_backend_interface = +{ .start = NULL, .destroy = wl_backend_iface_destroy, .get_drm_fd = NULL, @@ -185,7 +185,8 @@ registry_handle_global_remove(void *data, struct wl_registry *registry, // TODO } -static const struct wl_registry_listener registry_listener = { +static const struct wl_registry_listener registry_listener = +{ .global = registry_handle_global, .global_remove = registry_handle_global_remove, }; diff --git a/src/libds/backend/wayland/output.c b/src/libds/backend/wayland/output.c index b411dad..bc18875 100644 --- a/src/libds/backend/wayland/output.c +++ b/src/libds/backend/wayland/output.c @@ -1,13 +1,14 @@ #include #include + #include -#include "backend.h" #include "libds/log.h" #include "libds/output.h" - #include "xdg-shell-client-protocol.h" +#include "backend.h" + const struct ds_output_interface wl_output_iface; static const struct xdg_surface_listener wl_output_xdg_surface_listener; static const struct xdg_toplevel_listener wl_output_xdg_toplevel_listener; @@ -154,7 +155,8 @@ buffer_handle_release(void *data, struct wl_buffer *wl_buffer) ds_buffer_unlock(buffer->buffer); } -static const struct wl_buffer_listener buffer_listener = { +static const struct wl_buffer_listener buffer_listener = +{ .release = buffer_handle_release, }; @@ -223,7 +225,8 @@ surface_frame_callback(void *data, struct wl_callback *cb, uint32_t time) wl_signal_emit(&output->base.events.frame, &output->base); } -static const struct wl_callback_listener frame_listener = { +static const struct wl_callback_listener frame_listener = +{ .done = surface_frame_callback }; diff --git a/src/libds/buffer.c b/src/libds/buffer.c index 167d3a7..60b9925 100644 --- a/src/libds/buffer.c +++ b/src/libds/buffer.c @@ -1,11 +1,12 @@ #include #include -#include "buffer.h" -#include "client_buffer.h" #include "libds/log.h" #include "libds/interfaces/buffer.h" +#include "buffer.h" +#include "client_buffer.h" + static struct wl_array buffer_resource_interfaces = {0}; static void buffer_consider_destroy(struct ds_buffer *buffer); @@ -14,8 +15,8 @@ static const struct ds_buffer_resource_interface * get_buffer_resource_iface(struct wl_resource *resource); WL_EXPORT void -ds_buffer_init(struct ds_buffer *buffer, const struct ds_buffer_interface *iface, - int width, int height) +ds_buffer_init(struct ds_buffer *buffer, + const struct ds_buffer_interface *iface, int width, int height) { buffer->iface = iface; buffer->width = width; @@ -99,7 +100,8 @@ ds_buffer_begin_data_ptr_access(struct ds_buffer *buffer, uint32_t flags, assert(!buffer->accessing_data_ptr); if (!buffer->iface->begin_data_ptr_access) return false; - if (!buffer->iface->begin_data_ptr_access(buffer, flags, data, format, stride)) + if (!buffer->iface->begin_data_ptr_access(buffer, + flags, data, format, stride)) return false; buffer->accessing_data_ptr = true; return true; diff --git a/src/libds/client_buffer.h b/src/libds/client_buffer.h index cf390aa..a2aef6a 100644 --- a/src/libds/client_buffer.h +++ b/src/libds/client_buffer.h @@ -3,10 +3,11 @@ #include -#include "util.h" #include "libds/buffer.h" #include "libds/interfaces/buffer.h" +#include "util.h" + struct ds_shm_client_buffer { struct ds_buffer base; diff --git a/src/libds/client_buffer/shm_client_buffer.c b/src/libds/client_buffer/shm_client_buffer.c index 14bb745..6d52fb9 100644 --- a/src/libds/client_buffer/shm_client_buffer.c +++ b/src/libds/client_buffer/shm_client_buffer.c @@ -1,10 +1,12 @@ #include #include + #include +#include "libds/log.h" + #include "pixel_format.h" #include "buffer.h" -#include "libds/log.h" #include "client_buffer.h" static void @@ -37,7 +39,6 @@ shm_client_buffer_resource_handle_destroy(struct wl_listener *listener, struct ds_shm_client_buffer *buffer; buffer = wl_container_of(listener, buffer, listener.resource_destroy); - buffer->resource = NULL; buffer->shm_buffer = NULL; wl_list_remove(&buffer->listener.resource_destroy.link); @@ -83,8 +84,9 @@ shm_client_buffer_begin_data_ptr_access(struct ds_buffer *ds_buffer, *data = wl_shm_buffer_get_data(buffer->shm_buffer); wl_shm_buffer_begin_access(buffer->shm_buffer); } - else + else { return false; + } return true; } @@ -99,7 +101,8 @@ shm_client_buffer_end_data_ptr_access(struct ds_buffer *ds_buffer) wl_shm_buffer_end_access(buffer->shm_buffer); } -static const struct ds_buffer_interface shm_client_buffer_iface = { +static const struct ds_buffer_interface shm_client_buffer_iface = +{ .destroy = shm_client_buffer_destroy, .begin_data_ptr_access = shm_client_buffer_begin_data_ptr_access, .end_data_ptr_access = shm_client_buffer_end_data_ptr_access, diff --git a/src/libds/compositor.c b/src/libds/compositor.c index 64dd363..64b9a99 100644 --- a/src/libds/compositor.c +++ b/src/libds/compositor.c @@ -2,6 +2,7 @@ #include #include "libds/log.h" + #include "subcompositor.h" #include "surface.h" #include "region.h" @@ -85,9 +86,10 @@ static void compositor_handle_create_surface(struct wl_client *client, struct wl_resource *resource, uint32_t id) { - struct ds_compositor *compositor = wl_resource_get_user_data(resource); + struct ds_compositor *compositor; struct ds_surface *surface; + compositor = wl_resource_get_user_data(resource); surface = ds_surface_create(client, wl_resource_get_version(resource), id); if (!surface) { @@ -105,7 +107,8 @@ compositor_handle_create_region(struct wl_client *client, ds_region_add(client, wl_resource_get_version(resource), id); } -static const struct wl_compositor_interface compositor_impl = { +static const struct wl_compositor_interface compositor_impl = +{ .create_surface = compositor_handle_create_surface, .create_region = compositor_handle_create_region, }; @@ -130,8 +133,9 @@ static void compositor_bind(struct wl_client *client, void *data, static void compositor_handle_display_destroy(struct wl_listener *listener, void *data) { - struct ds_compositor *compositor = - wl_container_of(listener, compositor, display_destroy); + struct ds_compositor *compositor; + + compositor = wl_container_of(listener, compositor, display_destroy); ds_dbg("Destroy compositor(%p)", compositor); diff --git a/src/libds/log.c b/src/libds/log.c index 2777f9a..67386af 100644 --- a/src/libds/log.c +++ b/src/libds/log.c @@ -4,6 +4,7 @@ #include #include #include + #include #include "libds/log.h" @@ -51,6 +52,7 @@ WL_EXPORT void _ds_log(enum ds_log_level level, const char *fmt, ...) { va_list args; + va_start(args, fmt); log_callback(level, fmt, args); va_end(args); @@ -66,11 +68,12 @@ static void log_stderr(enum ds_log_level level, const char *fmt, va_list args) { bool colored_tty = false; + unsigned c; if (level > log_level) return; - unsigned c = (level < DS_LOG_LEVEL_LAST) ? level : DS_LOG_LEVEL_LAST - 1; + c = (level < DS_LOG_LEVEL_LAST) ? level : DS_LOG_LEVEL_LAST - 1; colored_tty = colored && isatty(STDERR_FILENO); if (colored_tty) @@ -89,7 +92,9 @@ static void log_wl(const char *fmt, va_list args) { static char ds_fmt[1024]; - int n = snprintf(ds_fmt, sizeof(ds_fmt), "[wayland] %s", fmt); + int n; + + n = snprintf(ds_fmt, sizeof(ds_fmt), "[wayland] %s", fmt); if (n > 0 && ds_fmt[n - 1] == '\n') ds_fmt[n - 1] = '\0'; _ds_vlog(DS_INF, ds_fmt, args); diff --git a/src/libds/pixel_format.c b/src/libds/pixel_format.c index 29da532..8676bec 100644 --- a/src/libds/pixel_format.c +++ b/src/libds/pixel_format.c @@ -1,4 +1,5 @@ #include + #include "pixel_format.h" uint32_t diff --git a/src/libds/presentation.c b/src/libds/presentation.c index d94ad04..54d10d9 100644 --- a/src/libds/presentation.c +++ b/src/libds/presentation.c @@ -1,3 +1,5 @@ +// TODO + #include "libds-private.h" #include "presentation-time-protocol.h" @@ -29,8 +31,6 @@ struct ds_presentation_feedback uint32_t psf_flags; }; - - static void presentation_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id); static void handle_display_destroy(struct wl_listener *listener, void *data); @@ -77,7 +77,8 @@ presentation_handle_feedback(struct wl_client *client, surface = ds_surface_from_resource(surface_resource); } -static const struct wp_presentation_interface presentation_impl = { +static const struct wp_presentation_interface presentation_impl = +{ .destroy = presentation_handle_destroy, .feedback = presentation_handle_feedback, }; diff --git a/src/libds/region.c b/src/libds/region.c index 27d30da..92fe003 100644 --- a/src/libds/region.c +++ b/src/libds/region.c @@ -3,9 +3,10 @@ #include #include -#include "region.h" #include "libds/log.h" +#include "region.h" + static const struct wl_region_interface region_impl; static void region_handle_resource_destroy(struct wl_resource *resource); @@ -127,9 +128,8 @@ ds_region_scale_xy(pixman_region32_t *dst, pixman_region32_t *src, pixman_box32_t *src_rects, *dst_rects; int nrects, i; - if (scale_x == 1.0 && scale_y == 1.0) { + if (scale_x == 1.0 && scale_y == 1.0) pixman_region32_copy(dst, src); - } src_rects = pixman_region32_rectangles(src, &nrects); dst_rects = malloc(nrects * sizeof *dst_rects); @@ -181,7 +181,8 @@ region_subtract(struct wl_client *client, struct wl_resource *resource, pixman_region32_fini(&rect); } -static const struct wl_region_interface region_impl = { +static const struct wl_region_interface region_impl = +{ .destroy = region_destroy, .add = region_add, .subtract = region_subtract, diff --git a/src/libds/subcompositor.c b/src/libds/subcompositor.c index 717fd33..9e821b3 100644 --- a/src/libds/subcompositor.c +++ b/src/libds/subcompositor.c @@ -1,6 +1,7 @@ +#include "libds/log.h" + #include "subcompositor.h" #include "surface.h" -#include "libds/log.h" #define SUBCOMPOSITOR_VERSION 1 @@ -40,9 +41,10 @@ subcompositor_handle_get_subsurface(struct wl_client *client, struct wl_resource *surface_resource, struct wl_resource *parent_resource) { - struct ds_surface *surface = ds_surface_from_resource(surface_resource); - struct ds_surface *parent = ds_surface_from_resource(parent_resource); + struct ds_surface *surface, *parent; + surface = ds_surface_from_resource(surface_resource); + parent = ds_surface_from_resource(parent_resource); if (surface == parent) { ds_inf("ds_surface(%p) cannot be its own parent", surface); wl_resource_post_error(resource, @@ -75,7 +77,8 @@ subcompositor_handle_get_subsurface(struct wl_client *client, wl_resource_get_version(resource), id); } -static const struct wl_subcompositor_interface subcompositor_impl = { +static const struct wl_subcompositor_interface subcompositor_impl = +{ .destroy = subcompositor_handle_destroy, .get_subsurface = subcompositor_handle_get_subsurface, }; diff --git a/src/libds/surface/subsurface.c b/src/libds/surface/subsurface.c index 4cc1ad8..2ec0dae 100644 --- a/src/libds/surface/subsurface.c +++ b/src/libds/surface/subsurface.c @@ -3,6 +3,7 @@ #include "libds/log.h" #include "libds/surface.h" + #include "surface-private.h" static const struct wl_subsurface_interface subsurface_impl; @@ -88,7 +89,8 @@ ds_subsurface_get_parent(struct ds_subsurface *subsurface) return subsurface->parent; } -static const struct ds_surface_role subsurface_role = { +static const struct ds_surface_role subsurface_role = +{ .name = "wl_subsurface", }; @@ -212,7 +214,8 @@ subsurface_handle_set_desync(struct wl_client *client, } } -static const struct wl_subsurface_interface subsurface_impl = { +static const struct wl_subsurface_interface subsurface_impl = +{ .destroy = subsurface_handle_destroy, .set_position = subsurface_handle_set_position, .place_above = subsurface_handle_place_above, diff --git a/src/libds/surface/surface-private.h b/src/libds/surface/surface-private.h index 78b2900..aee9547 100644 --- a/src/libds/surface/surface-private.h +++ b/src/libds/surface/surface-private.h @@ -2,6 +2,7 @@ #define DS_SURFACE_PRIVATE_H #include + #include #include diff --git a/src/libds/surface/surface.c b/src/libds/surface/surface.c index 32ab232..0333561 100644 --- a/src/libds/surface/surface.c +++ b/src/libds/surface/surface.c @@ -1,13 +1,13 @@ #include #include -#include "surface-private.h" -#include "region.h" -#include "util.h" - #include "libds/log.h" #include "libds/surface.h" +#include "region.h" +#include "util.h" +#include "surface-private.h" + #define CALLBACK_VERSION 1 static const struct wl_surface_interface surface_impl; @@ -335,9 +335,11 @@ static void surface_handle_set_input_region(struct wl_client *client, struct wl_resource *resource, struct wl_resource *region_resource) { - struct ds_surface *surface = wl_resource_get_user_data(resource); + struct ds_surface *surface; pixman_region32_t *region; + surface = wl_resource_get_user_data(resource); + ds_dbg("ds_surface(%p) set input region", surface); surface->pending.committed |= DS_SURFACE_STATE_INPUT_REGION; @@ -379,7 +381,9 @@ static void surface_handle_set_buffer_transform(struct wl_client *client, struct wl_resource *resource, int32_t transform) { - struct ds_surface *surface = wl_resource_get_user_data(resource); + struct ds_surface *surface; + + surface = wl_resource_get_user_data(resource); ds_dbg("ds_surface(%p) set buffer transform(%d)", surface, transform); @@ -400,7 +404,9 @@ static void surface_handle_set_buffer_scale(struct wl_client *client, struct wl_resource *resource, int32_t scale) { - struct ds_surface *surface = wl_resource_get_user_data(resource); + struct ds_surface *surface; + + surface = wl_resource_get_user_data(resource); ds_dbg("ds_surface(%p) set buffer scale(%d)", surface, scale); @@ -421,7 +427,9 @@ surface_handle_damage_buffer(struct wl_client *client, struct wl_resource *resource, int32_t x, int32_t y, int32_t width, int32_t height) { - struct ds_surface *surface = wl_resource_get_user_data(resource); + struct ds_surface *surface; + + surface = wl_resource_get_user_data(resource); ds_dbg("ds_surface(%p) damage: x %d y %d width %d height %d", surface, x, y, width, height); @@ -438,7 +446,8 @@ surface_handle_damage_buffer(struct wl_client *client, x, y, width, height); } -static const struct wl_surface_interface surface_impl = { +static const struct wl_surface_interface surface_impl = +{ .destroy = surface_handle_destroy, .attach = surface_handle_attach, .damage = surface_handle_damage, @@ -454,7 +463,9 @@ static const struct wl_surface_interface surface_impl = { static void surface_handle_resource_destroy(struct wl_resource *resource) { - struct ds_surface *surface = wl_resource_get_user_data(resource); + struct ds_surface *surface; + + surface = wl_resource_get_user_data(resource); ds_inf("Destroy ds_surface %p (res %p)", surface, surface->resource); diff --git a/src/libds/swapchain.c b/src/libds/swapchain.c index 54e64cf..78a2ece 100644 --- a/src/libds/swapchain.c +++ b/src/libds/swapchain.c @@ -41,7 +41,7 @@ struct ds_swapchain * ds_swapchain_create(struct ds_allocator *alloc, int width, int height, uint32_t format) { - struct ds_swapchain *swapchain = NULL; + struct ds_swapchain *swapchain; swapchain = calloc(1, sizeof *swapchain); if (!swapchain) diff --git a/src/libds/util/time.c b/src/libds/util/time.c index 1b17516..afb0e89 100644 --- a/src/libds/util/time.c +++ b/src/libds/util/time.c @@ -3,6 +3,8 @@ #include #include -int64_t timespec_to_msec(const struct timespec *a) { +int64_t +timespec_to_msec(const struct timespec *a) +{ return (int64_t)a->tv_sec * 1000 + a->tv_nsec / 1000000; } diff --git a/src/libds/xdg_shell/xdg_shell.c b/src/libds/xdg_shell/xdg_shell.c index b7cc8ff..a53684a 100644 --- a/src/libds/xdg_shell/xdg_shell.c +++ b/src/libds/xdg_shell/xdg_shell.c @@ -2,14 +2,16 @@ #include #include -#include "xdg_shell.h" #include "libds/log.h" #include "libds/xdg_shell.h" +#include "xdg_shell.h" + #define XDG_WM_BASE_VERSION 2 #define XDG_SHELL_PING_TIMEOUT 10000 -static void xdg_shell_handle_display_destroy(struct wl_listener *listener, void *data); +static void xdg_shell_handle_display_destroy(struct wl_listener *listener, + void *data); static void xdg_shell_bind(struct wl_client *wl_client, void *data, uint32_t verison, uint32_t id); @@ -126,7 +128,8 @@ xdg_shell_handle_pong(struct wl_client *wl_client, client->ping_serial = 0; } -static const struct xdg_wm_base_interface xdg_shell_impl = { +static const struct xdg_wm_base_interface xdg_shell_impl = +{ .destroy = xdg_shell_handle_destroy, .create_positioner = xdg_shell_handle_create_positioner, .get_xdg_surface = xdg_shell_handle_get_xdg_surface, @@ -150,11 +153,9 @@ xdg_client_handle_resource_destroy(struct wl_resource *resource) static int xdg_client_handle_ping_timeout(void *user_data) { - struct ds_xdg_client *client; + struct ds_xdg_client *client = user_data; struct ds_xdg_surface *surface; - client = user_data; - wl_list_for_each(surface, &client->surfaces, link) wl_signal_emit(&surface->events.ping_timeout, surface); @@ -181,11 +182,9 @@ static void xdg_shell_bind(struct wl_client *wl_client, void *data, uint32_t version, uint32_t id) { - struct ds_xdg_shell *shell; + struct ds_xdg_shell *shell = data; struct ds_xdg_client *client; - shell = data; - client = calloc(1, sizeof *client); if (client == NULL) { wl_client_post_no_memory(wl_client); diff --git a/src/libds/xdg_shell/xdg_shell.h b/src/libds/xdg_shell/xdg_shell.h index 6596ea2..ea67be7 100644 --- a/src/libds/xdg_shell/xdg_shell.h +++ b/src/libds/xdg_shell/xdg_shell.h @@ -3,10 +3,10 @@ #include +#include "libds/output.h" #include "xdg-shell-server-protocol.h" #include "surface.h" -#include "libds/output.h" enum ds_xdg_surface_role { diff --git a/src/libds/xdg_shell/xdg_surface.c b/src/libds/xdg_shell/xdg_surface.c index 523438d..1e1654e 100644 --- a/src/libds/xdg_shell/xdg_surface.c +++ b/src/libds/xdg_shell/xdg_surface.c @@ -1,10 +1,12 @@ #include #include -#include "xdg_shell.h" #include "libds/log.h" +#include "xdg_shell.h" + static const struct xdg_surface_interface xdg_surface_impl; + static void xdg_surface_handle_surface_destroy(struct wl_listener *listener, void *data); static void xdg_surface_handle_surface_commit(struct wl_listener *listener, diff --git a/src/libds/xdg_shell/xdg_toplevel.c b/src/libds/xdg_shell/xdg_toplevel.c index 8e78fe7..2a1e6d7 100644 --- a/src/libds/xdg_shell/xdg_toplevel.c +++ b/src/libds/xdg_shell/xdg_toplevel.c @@ -4,7 +4,8 @@ #include "xdg_shell.h" -const struct ds_surface_role xdg_toplevel_surface_role = { +static const struct ds_surface_role xdg_toplevel_surface_role = +{ .name = "xdg_toplevel", .commit = handle_xdg_surface_commit, }; @@ -17,9 +18,8 @@ void create_xdg_toplevel(struct ds_xdg_surface *surface, uint32_t id) { if (!ds_surface_set_role(surface->ds_surface, &xdg_toplevel_surface_role, - surface, surface->resource, XDG_WM_BASE_ERROR_ROLE)) { + surface, surface->resource, XDG_WM_BASE_ERROR_ROLE)) return; - } if (surface->role != DS_XDG_SURFACE_ROLE_NONE) { wl_resource_post_error(surface->resource, @@ -81,6 +81,7 @@ send_xdg_toplevel_configure(struct ds_xdg_surface *surface, struct ds_xdg_surface_configure *configure) { struct wl_array states; + uint32_t width, height; configure->toplevel_configure = malloc(sizeof *configure->toplevel_configure); @@ -125,8 +126,8 @@ send_xdg_toplevel_configure(struct ds_xdg_surface *surface, // TODO } - uint32_t width = surface->toplevel->scheduled.width; - uint32_t height = surface->toplevel->scheduled.height; + width = surface->toplevel->scheduled.width; + height = surface->toplevel->scheduled.height; xdg_toplevel_send_configure(surface->toplevel->resource, width, height, &states); @@ -297,7 +298,8 @@ xdg_toplevel_handle_set_minimized(struct wl_client *client, wl_signal_emit(&surface->toplevel->events.request_maximize, surface); } -static const struct xdg_toplevel_interface xdg_toplevel_impl = { +static const struct xdg_toplevel_interface xdg_toplevel_impl = +{ xdg_toplevel_handle_destroy, xdg_toplevel_handle_set_parent, xdg_toplevel_handle_set_title, -- 2.7.4 From 3ced4a58950ed06b3c5d3fd30655cb4d3e6406e3 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Fri, 4 Mar 2022 14:49:34 +0900 Subject: [PATCH 07/16] Remove too noisy logs Change-Id: I8e4051464641323a3d08bfa230c2f09f3ccd9bf7 --- src/libds/backend/tdm/output.c | 2 -- src/libds/backend/wayland/output.c | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/libds/backend/tdm/output.c b/src/libds/backend/tdm/output.c index 958b8ce..5148853 100644 --- a/src/libds/backend/tdm/output.c +++ b/src/libds/backend/tdm/output.c @@ -197,8 +197,6 @@ output_iface_commit(struct ds_output *ds_output) } } - ds_dbg("Swap Buffer!!!!!"); - return true; } diff --git a/src/libds/backend/wayland/output.c b/src/libds/backend/wayland/output.c index bc18875..1966a97 100644 --- a/src/libds/backend/wayland/output.c +++ b/src/libds/backend/wayland/output.c @@ -257,8 +257,6 @@ wl_output_iface_commit(struct ds_output *ds_output) wl_surface_attach(output->surface, buffer->wl_buffer, 0, 0); wl_surface_damage_buffer(output->surface, 0, 0, INT32_MAX, INT32_MAX); wl_surface_commit(output->surface); - - ds_dbg("Swap Buffer!!!!!"); } wl_display_flush(output->backend->server.display); -- 2.7.4 From e149285df5dc7c8729ff23775c7bd2f99d726079 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Fri, 4 Mar 2022 16:27:16 +0900 Subject: [PATCH 08/16] output: Add ds_output_enable/disable APIs Change-Id: I0e267ad8e411462487529bfde3d732a845903773 --- include/libds/interfaces/output.h | 2 ++ include/libds/output.h | 6 ++++++ src/libds/output.c | 25 +++++++++++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/include/libds/interfaces/output.h b/include/libds/interfaces/output.h index 9b95db1..6fb2909 100644 --- a/include/libds/interfaces/output.h +++ b/include/libds/interfaces/output.h @@ -60,6 +60,8 @@ struct ds_output struct wl_signal frame; struct wl_signal commit; } events; + + bool enabled; }; void diff --git a/include/libds/output.h b/include/libds/output.h index c7ee476..cae9f7f 100644 --- a/include/libds/output.h +++ b/include/libds/output.h @@ -20,6 +20,12 @@ struct ds_output_mode { void ds_output_destroy(struct ds_output *output); +void +ds_output_enable(struct ds_output *output); + +void +ds_output_disable(struct ds_output *output); + bool ds_output_commit(struct ds_output *output); diff --git a/src/libds/output.c b/src/libds/output.c index 4f67056..bc286f7 100644 --- a/src/libds/output.c +++ b/src/libds/output.c @@ -7,6 +7,7 @@ static void output_handle_display_destroy(struct wl_listener *listener, void *data); +static void output_enable(struct ds_output *output, bool enable); static void output_state_clear(struct ds_output_state *state); static void output_state_clear_buffer(struct ds_output_state *state); @@ -43,6 +44,18 @@ ds_output_destroy(struct ds_output *output) free(output); } +void +ds_output_enable(struct ds_output *output) +{ + output_enable(output, true); +} + +void +ds_output_disable(struct ds_output *output) +{ + output_enable(output, false); +} + WL_EXPORT bool ds_output_commit(struct ds_output *output) { @@ -147,3 +160,15 @@ output_state_clear_buffer(struct ds_output_state *state) state->committed &= ~DS_OUTPUT_STATE_BUFFER; } + +static void +output_enable(struct ds_output *output, bool enable) +{ + if (output->enabled == enable) { + output->pending.committed &= ~DS_OUTPUT_STATE_ENABLED; + return; + } + + output->pending.committed |= DS_OUTPUT_STATE_ENABLED; + output->pending.enabled = enable; +} -- 2.7.4 From 7d45a0322bbbc455c9fd8b9582e01b15e2de96df Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Tue, 8 Mar 2022 16:21:28 +0900 Subject: [PATCH 09/16] Build 'include' subdir after 'src' A variable 'features' referred from 'include' subdir is set during build of 'src'. Change-Id: I541215320de7100e22d9c0a1a7eed4100c021397 --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index db1f43c..0e4e5c0 100644 --- a/meson.build +++ b/meson.build @@ -30,8 +30,8 @@ features = { 'tbm-allocator': false, } -subdir('include') subdir('src') +subdir('include') configure_file(output: 'config.h', install: false, configuration: cdata) -- 2.7.4 From 97cd1fa2babc9a6bc5ab30afcbc5a5621d7f3c5f Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Wed, 16 Mar 2022 11:43:49 +0900 Subject: [PATCH 10/16] Add directories for tizen features Change-Id: Ia3a389e793d6ecb3a20e783059fd301e432f73bc --- include/{libds => libds-tizen}/allocator/tbm.h | 4 +-- include/{libds => libds-tizen}/backend/tdm.h | 4 +-- include/meson.build | 16 +++++------- meson.build | 7 ------ meson_options.txt | 2 +- packaging/libds.spec | 25 +++++++++++++++--- src/examples/meson.build | 4 ++- src/examples/tdm-backend.c | 4 +-- src/examples/tinyds-tdm.c | 4 +-- src/libds-tizen/allocator/meson.build | 2 ++ src/{libds => libds-tizen}/allocator/tbm.c | 0 src/libds-tizen/backend/meson.build | 1 + src/{libds => libds-tizen}/backend/tdm/backend.c | 0 src/libds-tizen/backend/tdm/meson.build | 12 +++++++++ src/{libds => libds-tizen}/backend/tdm/output.c | 2 +- src/{libds => libds-tizen}/backend/tdm/tdm.h | 4 +-- src/libds-tizen/meson.build | 29 +++++++++++++++++++++ src/libds/allocator/meson.build | 11 -------- src/libds/backend/meson.build | 14 ----------- src/libds/backend/tdm/meson.build | 32 ------------------------ src/libds/meson.build | 7 ------ src/meson.build | 3 +++ 22 files changed, 90 insertions(+), 97 deletions(-) rename include/{libds => libds-tizen}/allocator/tbm.h (76%) rename include/{libds => libds-tizen}/backend/tdm.h (72%) create mode 100644 src/libds-tizen/allocator/meson.build rename src/{libds => libds-tizen}/allocator/tbm.c (100%) create mode 100644 src/libds-tizen/backend/meson.build rename src/{libds => libds-tizen}/backend/tdm/backend.c (100%) create mode 100644 src/libds-tizen/backend/tdm/meson.build rename src/{libds => libds-tizen}/backend/tdm/output.c (99%) rename src/{libds => libds-tizen}/backend/tdm/tdm.h (95%) create mode 100644 src/libds-tizen/meson.build delete mode 100644 src/libds/backend/tdm/meson.build diff --git a/include/libds/allocator/tbm.h b/include/libds-tizen/allocator/tbm.h similarity index 76% rename from include/libds/allocator/tbm.h rename to include/libds-tizen/allocator/tbm.h index c02aee3..3febb10 100644 --- a/include/libds/allocator/tbm.h +++ b/include/libds-tizen/allocator/tbm.h @@ -1,5 +1,5 @@ -#ifndef LIBDS_ALLOCATOR_TBM_H -#define LIBDS_ALLOCATOR_TBM_H +#ifndef LIBDS_TIZEN_ALLOCATOR_TBM_H +#define LIBDS_TIZEN_ALLOCATOR_TBM_H #include diff --git a/include/libds/backend/tdm.h b/include/libds-tizen/backend/tdm.h similarity index 72% rename from include/libds/backend/tdm.h rename to include/libds-tizen/backend/tdm.h index e697413..d2785b2 100644 --- a/include/libds/backend/tdm.h +++ b/include/libds-tizen/backend/tdm.h @@ -1,5 +1,5 @@ -#ifndef LIBDS_BACKEND_TDM_H -#define LIBDS_BACKEND_TDM_H +#ifndef LIBDS_TIZEN_BACKEND_TDM_H +#define LIBDS_TIZEN_BACKEND_TDM_H #include diff --git a/include/meson.build b/include/meson.build index f273424..0975c5d 100644 --- a/include/meson.build +++ b/include/meson.build @@ -1,13 +1,9 @@ -exclude_files = [] -if not features.get('tdm-backend') - exclude_files += 'backend/tdm.h' -endif - -if not features.get('tbm-allocator') - exclude_files += 'allocator/tbm.h' -endif - install_subdir('libds', install_dir: get_option('includedir'), - exclude_files: exclude_files, ) + +if get_option('tizen') + install_subdir('libds-tizen', + install_dir: get_option('includedir'), + ) +endif diff --git a/meson.build b/meson.build index 0e4e5c0..d3d2df0 100644 --- a/meson.build +++ b/meson.build @@ -25,14 +25,7 @@ cdata.set('LIBDS_VERSION_MAJOR', libds_version_major) cdata.set('LIBDS_VERSION_MINOR', libds_version_minor) cdata.set('LIBDS_VERSION_PATCH', libds_version_patch) -features = { - 'tdm-backend': false, - 'tbm-allocator': false, -} - subdir('src') subdir('include') configure_file(output: 'config.h', install: false, configuration: cdata) - -summary(features, bool_yn: true) diff --git a/meson_options.txt b/meson_options.txt index 02af9b0..6ef6c8e 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1 +1 @@ -option('backends', type: 'array', choices: ['auto', 'tdm'], value: ['auto'], description: 'Select built-in backends') +option('tizen', type: 'boolean', value: false, description: 'Build Tizen features') diff --git a/packaging/libds.spec b/packaging/libds.spec index bd38de7..879a87d 100644 --- a/packaging/libds.spec +++ b/packaging/libds.spec @@ -30,6 +30,12 @@ Requires: %{name} = %{version}-%{release} %description devel Development package of Wayland Compositor Library +%package tizen-devel +Summary: Wayland Compositor development package on Tizen + +%description tizen-devel +Wayland Compositor development library for Tizen platform + %prep %setup -q cp %{SOURCE1001} . @@ -39,7 +45,8 @@ meson setup \ --prefix /usr \ --libdir %{_libdir} \ --bindir %{_bindir} \ - builddir + builddir \ + -Dtizen=true ninja -C builddir all %install @@ -56,7 +63,19 @@ ninja -C builddir install %manifest %{name}.manifest %defattr(-,root,root,-) %license LICENSE -%{_includedir}/* +%{_includedir}/libds/* %{_libdir}/pkgconfig/libds.pc %{_libdir}/libds.so -%{_bindir}/* +%{_bindir}/wl-backend +%{_bindir}/tinyds + +%files tizen-devel +%manifest %{name}.manifest +%defattr(-,root,root,-) +%license LICENSE +%{_includedir}/libds-tizen/* +%{_libdir}/pkgconfig/libds-tizen.pc +%{_libdir}/libds-tizen.so +%{_bindir}/tdm-backend +%{_bindir}/tinyds-tdm +%{_bindir}/ds-simple-tbm diff --git a/src/examples/meson.build b/src/examples/meson.build index 193b4a5..f95bd50 100644 --- a/src/examples/meson.build +++ b/src/examples/meson.build @@ -23,7 +23,9 @@ executable('tinyds', install : true ) -if features.get('tdm-backend') +if get_option('tizen') + common_deps += dep_libds_tizen + executable('tdm-backend', 'tdm-backend.c', dependencies: common_deps, diff --git a/src/examples/tdm-backend.c b/src/examples/tdm-backend.c index ee39f06..ba3fecb 100644 --- a/src/examples/tdm-backend.c +++ b/src/examples/tdm-backend.c @@ -8,10 +8,10 @@ #include #include #include -#include -#include #include #include +#include +#include #define WIDTH 1280 #define HEIGHT 720 diff --git a/src/examples/tinyds-tdm.c b/src/examples/tinyds-tdm.c index 2c91a66..143d53e 100644 --- a/src/examples/tinyds-tdm.c +++ b/src/examples/tinyds-tdm.c @@ -14,11 +14,11 @@ #include #include #include -#include -#include #include #include #include +#include +#include #define TINYDS_UNUSED __attribute__((unused)) diff --git a/src/libds-tizen/allocator/meson.build b/src/libds-tizen/allocator/meson.build new file mode 100644 index 0000000..fe869bd --- /dev/null +++ b/src/libds-tizen/allocator/meson.build @@ -0,0 +1,2 @@ +libds_tizen_files += files('tbm.c') +libds_tizen_deps += dependency('libtbm', required: true) diff --git a/src/libds/allocator/tbm.c b/src/libds-tizen/allocator/tbm.c similarity index 100% rename from src/libds/allocator/tbm.c rename to src/libds-tizen/allocator/tbm.c diff --git a/src/libds-tizen/backend/meson.build b/src/libds-tizen/backend/meson.build new file mode 100644 index 0000000..8a05e13 --- /dev/null +++ b/src/libds-tizen/backend/meson.build @@ -0,0 +1 @@ +subdir('tdm') diff --git a/src/libds/backend/tdm/backend.c b/src/libds-tizen/backend/tdm/backend.c similarity index 100% rename from src/libds/backend/tdm/backend.c rename to src/libds-tizen/backend/tdm/backend.c diff --git a/src/libds-tizen/backend/tdm/meson.build b/src/libds-tizen/backend/tdm/meson.build new file mode 100644 index 0000000..39ffceb --- /dev/null +++ b/src/libds-tizen/backend/tdm/meson.build @@ -0,0 +1,12 @@ +libds_tizen_files += files( + 'backend.c', + 'output.c', +) + +libtdm = dependency('libtdm', required: true) +libtbm = dependency('libtbm', required: true) + +libds_tizen_deps += [ + libtdm, + libtbm +] diff --git a/src/libds/backend/tdm/output.c b/src/libds-tizen/backend/tdm/output.c similarity index 99% rename from src/libds/backend/tdm/output.c rename to src/libds-tizen/backend/tdm/output.c index 5148853..f6b6250 100644 --- a/src/libds/backend/tdm/output.c +++ b/src/libds-tizen/backend/tdm/output.c @@ -4,7 +4,7 @@ #include #include "libds/log.h" -#include "libds/allocator/tbm.h" +#include "libds-tizen/allocator/tbm.h" #include "tdm.h" diff --git a/src/libds/backend/tdm/tdm.h b/src/libds-tizen/backend/tdm/tdm.h similarity index 95% rename from src/libds/backend/tdm/tdm.h rename to src/libds-tizen/backend/tdm/tdm.h index 1c80ef9..275089c 100644 --- a/src/libds/backend/tdm/tdm.h +++ b/src/libds-tizen/backend/tdm/tdm.h @@ -1,5 +1,5 @@ -#ifndef DS_BACKEND_TDM_H -#define DS_BACKEND_TDM_H +#ifndef DS_TIZEN_BACKEND_TDM_H +#define DS_TIZEN_BACKEND_TDM_H #include diff --git a/src/libds-tizen/meson.build b/src/libds-tizen/meson.build new file mode 100644 index 0000000..e9ca734 --- /dev/null +++ b/src/libds-tizen/meson.build @@ -0,0 +1,29 @@ +libds_tizen_files = [] + +libds_tizen_deps = [ + dep_libds, +] + +subdir('allocator') +subdir('backend') + +lib_libds_tizen = shared_library('ds-tizen', libds_tizen_files, + dependencies: libds_tizen_deps, + include_directories: [ common_inc, include_directories('.') ], + version: meson.project_version(), + install: true +) + +dep_libds_tizen = declare_dependency( + link_with: lib_libds_tizen, + dependencies: libds_tizen_deps, + include_directories: [ common_inc, include_directories('.') ], +) + +pkgconfig = import('pkgconfig') +pkgconfig.generate(lib_libds_tizen, + version: meson.project_version(), + filebase: 'libds-tizen', + name: 'libds-tizen', + description: 'extension of libds for tizen platform', +) diff --git a/src/libds/allocator/meson.build b/src/libds/allocator/meson.build index 361f96e..173c219 100644 --- a/src/libds/allocator/meson.build +++ b/src/libds/allocator/meson.build @@ -1,12 +1 @@ libds_files += files('shm.c') - -libtbm = dependency( - 'libtbm', - required: false, - not_found_message: 'Required for TBM allocator support.' -) -if libtbm.found() - libds_files += files('tbm.c') - libds_deps += libtbm - features += { 'tbm-allocator': true } -endif diff --git a/src/libds/backend/meson.build b/src/libds/backend/meson.build index b1fff87..895ffca 100644 --- a/src/libds/backend/meson.build +++ b/src/libds/backend/meson.build @@ -1,15 +1 @@ -all_backends = ['tdm'] -backends = get_option('backends') -if 'auto' in backends and get_option('auto_features').enabled() - backends = all_backends -elif 'auto' in backends and get_option('auto_features').disabled() - backends = [] -endif - -foreach backend : all_backends - if backend in backends or 'auto' in backends - subdir(backend) - endif -endforeach - subdir('wayland') diff --git a/src/libds/backend/tdm/meson.build b/src/libds/backend/tdm/meson.build deleted file mode 100644 index 82eb165..0000000 --- a/src/libds/backend/tdm/meson.build +++ /dev/null @@ -1,32 +0,0 @@ -msg = ['Required for TDM backend support.'] -if 'tdm' in backends - msg += 'Install "libtdm" and "libtbm", or disable the tdm backend' -endif - -libtdm = dependency( - 'libtdm', - required: 'tdm' in backends, - not_found_message: '\n'.join(msg) -) - -libtbm = dependency( - 'libtbm', - required: 'tdm' in backends, - not_found_message: '\n'.join(msg) -) - -if not libtdm.found() or not libtbm.found() - subdir_done() -endif - -libds_files += files( - 'backend.c', - 'output.c', -) - -libds_deps += [ - libtdm, - libtbm -] - -features += { 'tdm-backend': true } diff --git a/src/libds/meson.build b/src/libds/meson.build index ed8c95f..50f7962 100644 --- a/src/libds/meson.build +++ b/src/libds/meson.build @@ -68,16 +68,10 @@ lib_libds = shared_library('ds', libds_files, install: true ) -ds_vars = {} -foreach name, have : features - ds_vars += { 'have_' + name.underscorify(): have.to_string() } -endforeach - dep_libds = declare_dependency( link_with: lib_libds, dependencies: libds_deps, include_directories: [ common_inc, include_directories('.') ], - variables: ds_vars, ) pkgconfig = import('pkgconfig') @@ -86,5 +80,4 @@ pkgconfig.generate(lib_libds, filebase: meson.project_name(), name: meson.project_name(), description: 'Wayland compositor library', - variables: ds_vars, ) diff --git a/src/meson.build b/src/meson.build index 774c7eb..d739bfe 100644 --- a/src/meson.build +++ b/src/meson.build @@ -11,6 +11,9 @@ wayland_scanner = find_program( ) subdir('libds') +if get_option('tizen') + subdir('libds-tizen') +endif subdir('tests') subdir('examples') subdir('clients') -- 2.7.4 From aa3d710937ec336e6fc7962f2927397d22e768e0 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Wed, 16 Mar 2022 13:18:21 +0900 Subject: [PATCH 11/16] libds-tizen: Add ds_tdm_buffer_queue A ds_tdm_buffer_queue is a buffer queue that is able to be acquired from ds_tdm_output. A ds_tdm_buffer_queue provides a handle of native queue to a user and the user may pass it to a renderer. The renderer then should think of native queue as tbm_surface_queue_h. With the tbm_surface_queue_h, the renderer may dequeue a surface from it and draw on the dequeued buffer. After finish drawing on the buffer, the renderer should enqueue it to the tbm_surface_queue_h. As soon as the renderer enqueues buffer to the tbm_surface_queue_h, the user can recieve a notification that the buffer can be acquired from the ds_tbm_buffer_queue using ds_tdm_buffer_queue_add_acquirable_listener(). Then user may acquire a buffer from the ds_tdm_buffer_queue and attach it to a ds_output. Note that although the renderer may enqueue a buffer on different thread from the thread working on libds, but libds will call a callback function which is registered using ds_tdm_buffer_queue_add_acquirable_listener() on the thread working on libds. Change-Id: Ia5c477ceabda7e85f6441a73e76884b95eafa6fb --- include/libds-tizen/backend/tdm.h | 21 ++ src/libds-tizen/backend/tdm/meson.build | 1 + src/libds-tizen/backend/tdm/output.c | 107 +++++++-- src/libds-tizen/backend/tdm/tdm.h | 5 +- src/libds-tizen/backend/tdm/tdm_buffer_queue.c | 311 +++++++++++++++++++++++++ src/libds-tizen/backend/tdm/tdm_buffer_queue.h | 45 ++++ 6 files changed, 464 insertions(+), 26 deletions(-) create mode 100644 src/libds-tizen/backend/tdm/tdm_buffer_queue.c create mode 100644 src/libds-tizen/backend/tdm/tdm_buffer_queue.h diff --git a/include/libds-tizen/backend/tdm.h b/include/libds-tizen/backend/tdm.h index d2785b2..8c5c605 100644 --- a/include/libds-tizen/backend/tdm.h +++ b/include/libds-tizen/backend/tdm.h @@ -2,14 +2,35 @@ #define LIBDS_TIZEN_BACKEND_TDM_H #include +#include #ifdef __cplusplus extern "C" { #endif +struct ds_tdm_output; + +struct ds_tdm_buffer_queue; + struct ds_backend * ds_tdm_backend_create(struct wl_display *display); +struct ds_tdm_output * +ds_tdm_output_from_output(struct ds_output *ds_output); + +struct ds_tdm_buffer_queue * +ds_tdm_output_get_buffer_queue(struct ds_tdm_output *output); + +void * +ds_tdm_buffer_queue_get_native_queue(struct ds_tdm_buffer_queue *queue); + +struct ds_buffer * +ds_tdm_buffer_queue_acquire(struct ds_tdm_buffer_queue *queue); + +void +ds_tdm_buffer_queue_add_acquirable_listener(struct ds_tdm_buffer_queue *queue, + struct wl_listener *listener); + #ifdef __cplusplus } #endif diff --git a/src/libds-tizen/backend/tdm/meson.build b/src/libds-tizen/backend/tdm/meson.build index 39ffceb..932559f 100644 --- a/src/libds-tizen/backend/tdm/meson.build +++ b/src/libds-tizen/backend/tdm/meson.build @@ -1,6 +1,7 @@ libds_tizen_files += files( 'backend.c', 'output.c', + 'tdm_buffer_queue.c', ) libtdm = dependency('libtdm', required: true) diff --git a/src/libds-tizen/backend/tdm/output.c b/src/libds-tizen/backend/tdm/output.c index f6b6250..10b9666 100644 --- a/src/libds-tizen/backend/tdm/output.c +++ b/src/libds-tizen/backend/tdm/output.c @@ -7,6 +7,7 @@ #include "libds-tizen/allocator/tbm.h" #include "tdm.h" +#include "tdm_buffer_queue.h" static const struct ds_output_interface tdm_output_iface; static bool output_init_modes(struct ds_tdm_output *output); @@ -17,6 +18,32 @@ static bool output_set_pending_fb(struct ds_tdm_output *output, struct ds_buffer *ds_buffer); static bool output_hwc_commit(struct ds_tdm_output *output); +WL_EXPORT struct ds_tdm_output * +ds_tdm_output_from_output(struct ds_output *ds_output) +{ + if (ds_output->iface != &tdm_output_iface) { + ds_err("Given ds_output is not for ds_tdm_output"); + return NULL; + } + + return (struct ds_tdm_output *)ds_output; +} + +WL_EXPORT struct ds_tdm_buffer_queue * +ds_tdm_output_get_buffer_queue(struct ds_tdm_output *output) +{ + if (output->queue) + return output->queue; + + output->queue = create_buffer_queue(output); + if (!output->queue) { + ds_err("Could not create tbm_queue with output(%p)", output); + return NULL; + } + + return output->queue; +} + struct ds_tdm_output * create_tdm_output(struct ds_tdm_backend *tdm, tdm_output *tdm_output) { @@ -89,12 +116,25 @@ destroy_tdm_buffer(struct ds_tdm_buffer *buffer) if (buffer == NULL) return; + if (!buffer->released) + wl_list_remove(&buffer->buffer_release.link); + wl_list_remove(&buffer->buffer_destroy.link); wl_list_remove(&buffer->link); free(buffer); } static void +buffer_handle_buffer_release(struct wl_listener *listener, void *data) +{ + struct ds_tdm_buffer *buffer; + + buffer = wl_container_of(listener, buffer, buffer_release); + wl_list_remove(&buffer->buffer_release.link); + buffer->released = true; +} + +static void buffer_handle_buffer_destroy(struct wl_listener *listener, void *data) { struct ds_tdm_buffer *buffer; @@ -120,7 +160,7 @@ create_tdm_buffer(struct ds_tdm_backend *backend, struct ds_buffer *ds_buffer) return NULL; buffer->surface = surface; - buffer->buffer = ds_buffer_lock(ds_buffer); + buffer->buffer = ds_buffer; wl_list_insert(&backend->buffers, &buffer->link); buffer->buffer_destroy.notify = buffer_handle_buffer_destroy; @@ -137,37 +177,38 @@ get_or_create_tdm_buffer(struct ds_tdm_backend *backend, wl_list_for_each(buffer, &backend->buffers, link) { if (buffer->buffer == ds_buffer && buffer->released) { - buffer->released = false; - ds_buffer_lock(buffer->buffer); - return buffer; + goto out; } } - return create_tdm_buffer(backend, ds_buffer); -} + buffer = create_tdm_buffer(backend, ds_buffer); -static void -tdm_buffer_release(struct ds_tdm_buffer *buffer) -{ - buffer->released = true; - ds_buffer_unlock(buffer->buffer); +out: + buffer->released = false; + + buffer->buffer_release.notify = buffer_handle_buffer_release; + ds_buffer_add_release_listener(ds_buffer, &buffer->buffer_release); + + ds_buffer_lock(buffer->buffer); + + return buffer; } static void output_update_front_buffer(struct ds_tdm_output *output) { if (output->front_buffer) - tdm_buffer_release(output->front_buffer); + ds_buffer_unlock(output->front_buffer); output->front_buffer = output->back_buffer; output->back_buffer = NULL; } static void output_attach_back_buffer(struct ds_tdm_output *output, - struct ds_tdm_buffer *buffer) + struct ds_buffer *buffer) { if (output->back_buffer) - tdm_buffer_release(output->back_buffer); + ds_buffer_unlock(output->back_buffer); output->back_buffer = buffer; } @@ -192,9 +233,8 @@ output_iface_commit(struct ds_output *ds_output) if (!output_hwc_commit(output)) { ds_err("Could not commit tdm output"); - if (output->back_buffer) { - tdm_buffer_release(output->back_buffer); - } + if (output->back_buffer) + ds_buffer_unlock(output->back_buffer); } return true; @@ -217,10 +257,13 @@ output_destroy(struct ds_tdm_output *output) } if (output->back_buffer) - ds_buffer_unlock(output->back_buffer->buffer); + ds_buffer_unlock(output->back_buffer); if (output->front_buffer) - ds_buffer_unlock(output->front_buffer->buffer); + ds_buffer_unlock(output->front_buffer); + + if (output->queue) + buffer_queue_destroy(output->queue); free(output); } @@ -306,24 +349,38 @@ static bool output_set_pending_fb(struct ds_tdm_output *output, struct ds_buffer *ds_buffer) { + struct ds_tdm_queue_buffer *queue_buffer; struct ds_tdm_buffer *buffer; + tbm_surface_h surface = NULL; tdm_region fb_damage; tdm_error err; - buffer = get_or_create_tdm_buffer(output->backend, ds_buffer); - if (!buffer) - return false; + if (output->queue) { + queue_buffer = buffer_queue_find_buffer(output->queue, ds_buffer); + if (queue_buffer) { + ds_buffer_lock(ds_buffer); + surface = queue_buffer->surface; + } + } + + if (!surface) { + buffer = get_or_create_tdm_buffer(output->backend, ds_buffer); + if (!buffer) + return false; + + surface = buffer->surface; + } memset(&fb_damage, 0, sizeof(fb_damage)); err = tdm_hwc_set_client_target_buffer(output->tdm.hwc, - buffer->surface, fb_damage); + surface, fb_damage); if (err != TDM_ERROR_NONE) { ds_err("Could not set hwc client target buffer"); - ds_buffer_unlock(buffer->buffer); + ds_buffer_unlock(ds_buffer); return false; } - output_attach_back_buffer(output, buffer); + output_attach_back_buffer(output, ds_buffer); return true; } diff --git a/src/libds-tizen/backend/tdm/tdm.h b/src/libds-tizen/backend/tdm/tdm.h index 275089c..f19483f 100644 --- a/src/libds-tizen/backend/tdm/tdm.h +++ b/src/libds-tizen/backend/tdm/tdm.h @@ -40,7 +40,8 @@ struct ds_tdm_output struct ds_output base; struct ds_tdm_backend *backend; - struct ds_tdm_buffer *front_buffer, *back_buffer; + struct ds_tdm_buffer_queue *queue; + struct ds_buffer *front_buffer, *back_buffer; struct { tdm_output *output; @@ -57,6 +58,8 @@ struct ds_tdm_buffer struct ds_buffer *buffer; tbm_surface_h surface; struct wl_list link; // ds_wl_backend.buffers + + struct wl_listener buffer_release; struct wl_listener buffer_destroy; bool released; diff --git a/src/libds-tizen/backend/tdm/tdm_buffer_queue.c b/src/libds-tizen/backend/tdm/tdm_buffer_queue.c new file mode 100644 index 0000000..7a2a1aa --- /dev/null +++ b/src/libds-tizen/backend/tdm/tdm_buffer_queue.c @@ -0,0 +1,311 @@ +#include +#include +#include +#include + +#include "libds/log.h" +#include "libds/interfaces/buffer.h" + +#include "tdm.h" +#include "tdm_buffer_queue.h" + +static void +buffer_queue_handle_acquirable(tbm_surface_queue_h surface_queue, + void *data); +static struct ds_tdm_queue_buffer * +create_queue_buffer(struct ds_tdm_buffer_queue *queue, + tbm_surface_h surface); +static void queue_buffer_destroy(struct ds_tdm_queue_buffer *buffer); +static void queue_buffer_drop(struct ds_tdm_queue_buffer *buffer); +static struct ds_buffer * +queue_buffer_acquire(struct ds_tdm_queue_buffer *buffer); +static int buffer_queue_handle_acquirable_efd(int fd, uint32_t mask, + void *data); + +WL_EXPORT void * +ds_tdm_buffer_queue_get_native_queue(struct ds_tdm_buffer_queue *queue) +{ + return (void *)queue->tbm_surface_queue; +} + +WL_EXPORT struct ds_buffer * +ds_tdm_buffer_queue_acquire(struct ds_tdm_buffer_queue *queue) +{ + struct ds_tdm_queue_buffer *buffer; + tbm_surface_h surface; + tbm_surface_queue_error_e err; + + if (!tbm_surface_queue_can_acquire(queue->tbm_surface_queue, 0)) + return NULL; + + err = tbm_surface_queue_acquire(queue->tbm_surface_queue, &surface); + if (err != TBM_SURFACE_QUEUE_ERROR_NONE || + surface == NULL) { + ds_err("Could not acquire tbm_surface from queue(%p)", queue); + return NULL; + } + + wl_list_for_each(buffer, &queue->buffers, link) { + if (buffer->surface == surface) + return queue_buffer_acquire(buffer); + } + + buffer = create_queue_buffer(queue, surface); + if (!buffer) { + ds_err("Could not create tbm_queue_buffer with queue(%p)", queue); + return NULL; + } + + wl_list_insert(&queue->buffers, &buffer->link); + + return queue_buffer_acquire(buffer); +} + +WL_EXPORT void +ds_tdm_buffer_queue_add_acquirable_listener(struct ds_tdm_buffer_queue *queue, + struct wl_listener *listener) +{ + wl_signal_add(&queue->events.acquirable, listener); +} + +struct ds_tdm_buffer_queue * +create_buffer_queue(struct ds_tdm_output *output) +{ + struct ds_tdm_buffer_queue *queue; + tdm_error err; + + queue = calloc(1, sizeof *queue); + if (!queue) + return NULL; + + wl_list_init(&queue->buffers); + + wl_signal_init(&queue->events.acquirable); + + queue->tbm_surface_queue = + tdm_hwc_get_client_target_buffer_queue(output->tdm.hwc, &err); + if (err != TDM_ERROR_NONE || + queue->tbm_surface_queue == NULL) { + ds_err("Could not get target buffer queue: err(%d)", err); + free(queue); + return NULL; + } + + tbm_surface_queue_reset(queue->tbm_surface_queue, + output->base.pending.mode->width, + output->base.pending.mode->height, + tbm_surface_queue_get_format(queue->tbm_surface_queue)); + + /* The callback function for tbm_surface_queue_add_acquirable_cb() may be + * called on different thread. This eventfd is to emit a signal of + * events.acquirable on the thread getting this buffer queue. */ + queue->acquirable_efd = eventfd(0, EFD_NONBLOCK); + if (queue->acquirable_efd < 0) { + ds_log_errno(DS_ERR, + "Could not create eventfd for acquirable callback"); + free(queue); + return NULL; + } + + queue->acquirable_source = wl_event_loop_add_fd( + wl_display_get_event_loop(output->backend->wl_display), + queue->acquirable_efd, + WL_EVENT_READABLE, + buffer_queue_handle_acquirable_efd, + queue); + + tbm_surface_queue_add_acquirable_cb(queue->tbm_surface_queue, + buffer_queue_handle_acquirable, (void *)queue); + + return queue; +} + +void +buffer_queue_destroy(struct ds_tdm_buffer_queue *queue) +{ + struct ds_tdm_queue_buffer *buffer, *buffer_tmp; + + wl_list_for_each_safe(buffer, buffer_tmp, &queue->buffers, link) + queue_buffer_drop(buffer); + + wl_event_source_remove(queue->acquirable_source); + close(queue->acquirable_efd); + tbm_surface_queue_destroy(queue->tbm_surface_queue); + free(queue); +} + +struct ds_tdm_queue_buffer * +buffer_queue_find_buffer(struct ds_tdm_buffer_queue *queue, + struct ds_buffer *ds_buffer) +{ + struct ds_tdm_queue_buffer *buffer; + + wl_list_for_each(buffer, &queue->buffers, link) { + if (&buffer->base == ds_buffer) + return buffer; + } + + return NULL; +} + +static void +buffer_queue_handle_acquirable(tbm_surface_queue_h surface_queue, void *data) +{ + struct ds_tdm_buffer_queue *queue = data; + uint64_t acquirable = 1; + int ret; + + ret = write(queue->acquirable_efd, &acquirable, sizeof(acquirable)); + if (ret < 0) + ds_log_errno(DS_ERR, "Could not write eventfd for acquirable buffer"); +} + +static const struct ds_buffer_interface queue_buffer_iface; + +static struct ds_tdm_queue_buffer * +create_queue_buffer(struct ds_tdm_buffer_queue *queue, tbm_surface_h surface) +{ + struct ds_tdm_queue_buffer *buffer; + + buffer = calloc(1, sizeof *buffer); + if (!buffer) + return NULL; + + ds_buffer_init(&buffer->base, &queue_buffer_iface, + tbm_surface_get_width(surface), + tbm_surface_get_height(surface)); + + buffer->queue = queue; + buffer->surface = surface; + + return buffer; +} + +static void +queue_buffer_destroy(struct ds_tdm_queue_buffer *buffer) +{ + free(buffer); +} + +static struct ds_tdm_queue_buffer * +queue_buffer_from_buffer(struct ds_buffer *ds_buffer) +{ + assert(ds_buffer->iface == &queue_buffer_iface); + return (struct ds_tdm_queue_buffer *)ds_buffer; +} + +static void +queue_buffer_iface_destroy(struct ds_buffer *ds_buffer) +{ + struct ds_tdm_queue_buffer *buffer; + + buffer = queue_buffer_from_buffer(ds_buffer); + queue_buffer_destroy(buffer); +} + +static bool +queue_buffer_iface_begin_data_ptr_access(struct ds_buffer *ds_buffer, + uint32_t flags, void **data, uint32_t *format, size_t *stride) +{ + struct ds_tdm_queue_buffer *buffer; + tbm_surface_info_s info; + int tbm_access_flags = 0; + int ret; + + buffer = queue_buffer_from_buffer(ds_buffer); + + if (!buffer->surface) { + ds_err("No tbm_surface. It's a dropped buffer(%p)", buffer); + return false; + } + + if (flags & DS_BUFFER_DATA_PTR_ACCESS_READ) + tbm_access_flags |= TBM_OPTION_READ; + else if (flags & DS_BUFFER_DATA_PTR_ACCESS_WRITE) + tbm_access_flags |= TBM_OPTION_WRITE; + + ret = tbm_surface_map(buffer->surface, tbm_access_flags, &info); + if (ret != TBM_SURFACE_ERROR_NONE) { + ds_err("Could not map tbm_surface of buffer(%p)", buffer); + return false; + } + + *data = info.planes[0].ptr; + *format = info.format; + *stride = info.planes[0].stride; + + return true; +} + +static void +queue_buffer_iface_end_data_ptr_access(struct ds_buffer *ds_buffer) +{ + struct ds_tdm_queue_buffer *buffer; + + buffer = queue_buffer_from_buffer(ds_buffer); + if (!buffer->surface) { + ds_err("No tbm_surface. It's a dropped buffer(%p)", buffer); + return; + } + + tbm_surface_unmap(buffer->surface); +} + +static const struct ds_buffer_interface queue_buffer_iface = +{ + .destroy = queue_buffer_iface_destroy, + .begin_data_ptr_access = queue_buffer_iface_begin_data_ptr_access, + .end_data_ptr_access = queue_buffer_iface_end_data_ptr_access, +}; + +static void +queue_buffer_handle_buffer_release(struct wl_listener *listener, void *data) +{ + struct ds_tdm_queue_buffer *buffer; + + buffer = wl_container_of(listener, buffer, buffer_release); + + wl_list_remove(&buffer->buffer_release.link); + buffer->acquired = false; + + tbm_surface_queue_release(buffer->queue->tbm_surface_queue, + buffer->surface); +} + +static void +queue_buffer_drop(struct ds_tdm_queue_buffer *buffer) +{ + if (buffer->acquired) + wl_list_remove(&buffer->buffer_release.link); + + wl_list_remove(&buffer->link); + ds_buffer_drop(&buffer->base); + buffer->surface = NULL; +} + +static struct ds_buffer * +queue_buffer_acquire(struct ds_tdm_queue_buffer *buffer) +{ + assert(!buffer->acquired); + + buffer->acquired = true; + buffer->buffer_release.notify = queue_buffer_handle_buffer_release; + ds_buffer_add_release_listener(&buffer->base, &buffer->buffer_release); + + return ds_buffer_lock(&buffer->base); +} + +static int +buffer_queue_handle_acquirable_efd(int fd, uint32_t mask, void *data) +{ + struct ds_tdm_buffer_queue *queue = data; + uint64_t acquirable_event; + + if (read(fd, &acquirable_event, sizeof(acquirable_event)) < 0 && + errno != EAGAIN) + return -1; + + wl_signal_emit(&queue->events.acquirable, queue); + + return 0; +} diff --git a/src/libds-tizen/backend/tdm/tdm_buffer_queue.h b/src/libds-tizen/backend/tdm/tdm_buffer_queue.h new file mode 100644 index 0000000..774b7c3 --- /dev/null +++ b/src/libds-tizen/backend/tdm/tdm_buffer_queue.h @@ -0,0 +1,45 @@ +#ifndef DS_TIZEN_BACKEND_TDM_BUFFER_QUEUE_H +#define DS_TIZEN_BACKEND_TBM_BUFFER_QUEUE_H + +#include +#include + +#include "tdm.h" + +struct ds_tdm_buffer_queue +{ + tbm_surface_queue_h tbm_surface_queue; + struct wl_event_source *acquirable_source; + + struct wl_list buffers; // ds_tdm_queue_buffer.link + + struct { + struct wl_signal acquirable; + } events; + + int acquirable_efd; +}; + +struct ds_tdm_queue_buffer +{ + struct ds_buffer base; + + struct ds_tdm_output *output; + struct ds_tdm_buffer_queue *queue; + tbm_surface_h surface; + + struct wl_list link; + struct wl_listener buffer_release; + + bool acquired; +}; + +struct ds_tdm_buffer_queue *create_buffer_queue(struct ds_tdm_output *output); + +void buffer_queue_destroy(struct ds_tdm_buffer_queue *queue); + +struct ds_tdm_queue_buffer * +buffer_queue_find_buffer(struct ds_tdm_buffer_queue *queue, + struct ds_buffer *ds_buffer); + +#endif -- 2.7.4 From 082ff4eb7b58a49d8270752308f38159ce80f18f Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Thu, 17 Mar 2022 16:40:37 +0900 Subject: [PATCH 12/16] Add an example of using ds_tdm_buffer_queue Dependeing on the declaration of USE_TDM_BUFFER_QUEUE macro, tinyds-tdm may be run with ds_tbm_buffer_queue. Change-Id: I1d221d2d5eb94024902eea66d08f5973f1914771 --- src/examples/meson.build | 3 + src/examples/pixman-helper.c | 5 +- src/examples/pixman-helper.h | 3 + src/examples/pixman-tbm-helper.c | 64 +++++++++++ src/examples/pixman-tbm-helper.h | 13 +++ src/examples/tbm-server-helper.c | 24 ++-- src/examples/tbm-server-helper.h | 6 + src/examples/tinyds-tdm-renderer.c | 187 ++++++++++++++++++++++++++++++ src/examples/tinyds-tdm-renderer.h | 48 ++++++++ src/examples/tinyds-tdm.c | 227 +++++++++++++++++++++++++++++-------- 10 files changed, 520 insertions(+), 60 deletions(-) create mode 100644 src/examples/pixman-tbm-helper.c create mode 100644 src/examples/pixman-tbm-helper.h create mode 100644 src/examples/tinyds-tdm-renderer.c create mode 100644 src/examples/tinyds-tdm-renderer.h diff --git a/src/examples/meson.build b/src/examples/meson.build index f95bd50..c60b610 100644 --- a/src/examples/meson.build +++ b/src/examples/meson.build @@ -35,8 +35,10 @@ if get_option('tizen') tinyds_tdm_files = [ 'tinyds-tdm.c', + 'tinyds-tdm-renderer.c', 'tbm-server-helper.c', 'pixman-helper.c', + 'pixman-tbm-helper.c', ] executable('tinyds-tdm', tinyds_tdm_files, @@ -46,6 +48,7 @@ if get_option('tizen') dependency('libdrm', required: true), dependency('libtbm', required: true), dependency('wayland-tbm-server', required: true), + dependency('threads', required: true), ], install_dir: libds_bindir, install : true diff --git a/src/examples/pixman-helper.c b/src/examples/pixman-helper.c index 5d42ec6..36a22e8 100644 --- a/src/examples/pixman-helper.c +++ b/src/examples/pixman-helper.c @@ -5,8 +5,6 @@ static void destroy_pixman_image(pixman_image_t *image, void *data); static uint32_t convert_drm_format_to_pixman(uint32_t fmt); -static pixman_color_t *color_rgb888(pixman_color_t *tmp, - uint8_t r, uint8_t g, uint8_t b); pixman_image_t * pixman_image_from_buffer(struct ds_buffer *buffer, @@ -37,7 +35,6 @@ pixman_image_from_buffer(struct ds_buffer *buffer, return image; } - void pixman_image_fill_color(pixman_image_t *image, uint8_t r, uint8_t g, uint8_t b) { @@ -56,7 +53,7 @@ pixman_image_fill_color(pixman_image_t *image, uint8_t r, uint8_t g, uint8_t b) pixman_image_unref(color_image); } -static pixman_color_t * +pixman_color_t * color_rgb888(pixman_color_t *tmp, uint8_t r, uint8_t g, uint8_t b) { tmp->alpha = 65535; diff --git a/src/examples/pixman-helper.h b/src/examples/pixman-helper.h index aa039ff..99ceaca 100644 --- a/src/examples/pixman-helper.h +++ b/src/examples/pixman-helper.h @@ -12,4 +12,7 @@ void pixman_image_fill_color(pixman_image_t *image, uint8_t r, uint8_t g, uint8_t b); +pixman_color_t * +color_rgb888(pixman_color_t *tmp, uint8_t r, uint8_t g, uint8_t b); + #endif diff --git a/src/examples/pixman-tbm-helper.c b/src/examples/pixman-tbm-helper.c new file mode 100644 index 0000000..710eceb --- /dev/null +++ b/src/examples/pixman-tbm-helper.c @@ -0,0 +1,64 @@ +#include + +#include "pixman-tbm-helper.h" + +static uint32_t convert_tbm_format_to_pixman(uint32_t fmt); +static void destroy_tbm_pixman_image(pixman_image_t *image, void *data); + +pixman_image_t * +pixman_image_from_tbm_surface(tbm_surface_h surface, + enum ds_buffer_data_ptr_access_flag access_flag) +{ + pixman_image_t *image; + tbm_surface_info_s info; + uint32_t format; + int tbm_access_flag = 0; + int width, height; + int ret; + + width = tbm_surface_get_width(surface); + height = tbm_surface_get_height(surface); + + if (access_flag & DS_BUFFER_DATA_PTR_ACCESS_READ) + tbm_access_flag |= TBM_OPTION_READ; + if (access_flag & DS_BUFFER_DATA_PTR_ACCESS_WRITE) + tbm_access_flag |= TBM_OPTION_WRITE; + + ret = tbm_surface_map(surface, tbm_access_flag, &info); + assert(ret == TBM_SURFACE_ERROR_NONE); + + format = convert_tbm_format_to_pixman(info.format); + image = pixman_image_create_bits(format, width, height, + (uint32_t *)info.planes[0].ptr, + info.planes[0].stride); + assert(image); + + tbm_surface_internal_ref(surface); + + pixman_image_set_destroy_function(image, + destroy_tbm_pixman_image, surface); + + return image; +} + +static void +destroy_tbm_pixman_image(pixman_image_t *image, void *data) +{ + tbm_surface_h surface = data; + + tbm_surface_unmap(surface); + tbm_surface_internal_unref(surface); +} + +static uint32_t +convert_tbm_format_to_pixman(uint32_t fmt) +{ + switch (fmt) { + case TBM_FORMAT_XRGB8888: + return PIXMAN_x8r8g8b8; + case TBM_FORMAT_ARGB8888: + return PIXMAN_a8r8g8b8; + default: + assert(0 && "not reached"); + } +} diff --git a/src/examples/pixman-tbm-helper.h b/src/examples/pixman-tbm-helper.h new file mode 100644 index 0000000..bf9bd55 --- /dev/null +++ b/src/examples/pixman-tbm-helper.h @@ -0,0 +1,13 @@ +#ifndef EXAMPLES_PIXMAN_TBM_HELPER_H +#define EXAMPLES_PIXMAN_TBM_HELPER_H + +#include +#include +#include +#include + +pixman_image_t * +pixman_image_from_tbm_surface(tbm_surface_h surface, + enum ds_buffer_data_ptr_access_flag access_flag); + +#endif diff --git a/src/examples/tbm-server-helper.c b/src/examples/tbm-server-helper.c index bd3a34d..320ee4f 100644 --- a/src/examples/tbm-server-helper.c +++ b/src/examples/tbm-server-helper.c @@ -8,6 +8,8 @@ #include static const struct ds_buffer_resource_interface tbm_buffer_resource_iface; +static const struct ds_buffer_interface tbm_client_buffer_iface; + static void tbm_server_handle_display_destroy(struct wl_listener *listener, void *data); static struct tbm_client_buffer * @@ -42,6 +44,19 @@ tbm_server_init_display(struct tbm_server *tbm, struct wl_display *display) return true; } +struct tbm_client_buffer * +tbm_client_buffer_from_buffer(struct ds_buffer *ds_buffer) +{ + assert(ds_buffer->iface == &tbm_client_buffer_iface); + return (struct tbm_client_buffer *)ds_buffer; +} + +tbm_surface_h +tbm_client_buffer_get_tbm_surface(struct tbm_client_buffer *buffer) +{ + return buffer->surface; +} + static void tbm_server_handle_display_destroy(struct wl_listener *listener, void *data) { @@ -107,15 +122,6 @@ static const struct ds_buffer_resource_interface tbm_buffer_resource_iface = { .from_resource = tbm_buffer_resource_iface_from_resource, }; -static const struct ds_buffer_interface tbm_client_buffer_iface; - -static struct tbm_client_buffer * -tbm_client_buffer_from_buffer(struct ds_buffer *ds_buffer) -{ - assert(ds_buffer->iface == &tbm_client_buffer_iface); - return (struct tbm_client_buffer *)ds_buffer; -} - static void tbm_client_buffer_destroy(struct ds_buffer *ds_buffer) { diff --git a/src/examples/tbm-server-helper.h b/src/examples/tbm-server-helper.h index a82ad5b..609f370 100644 --- a/src/examples/tbm-server-helper.h +++ b/src/examples/tbm-server-helper.h @@ -32,4 +32,10 @@ bool tbm_server_init_display(struct tbm_server *tbm_server, struct wl_display *display); +struct tbm_client_buffer * +tbm_client_buffer_from_buffer(struct ds_buffer *ds_buffer); + +tbm_surface_h +tbm_client_buffer_get_tbm_surface(struct tbm_client_buffer *buffer); + #endif diff --git a/src/examples/tinyds-tdm-renderer.c b/src/examples/tinyds-tdm-renderer.c new file mode 100644 index 0000000..0074dc9 --- /dev/null +++ b/src/examples/tinyds-tdm-renderer.c @@ -0,0 +1,187 @@ +#include +#include + +#include + +#include "pixman-helper.h" +#include "pixman-tbm-helper.h" +#include "tinyds-tdm-renderer.h" + +static void renderer_setup_thread(struct tinyds_renderer *renderer); +static void *renderer_thread_func(void *data); +static void texture_destroy(struct tinyds_texture *texture); + +bool +init_renderer(struct tinyds_renderer *renderer) +{ + renderer->damaged = false; + + wl_list_init(&renderer->textures); + + renderer_setup_thread(renderer); + + return true; +} + +void +fini_renderer(struct tinyds_renderer *renderer) +{ + pthread_mutex_lock(&renderer->mutex); + + renderer->destroying = true; + pthread_cond_signal(&renderer->cond); + + pthread_mutex_unlock(&renderer->mutex); + + pthread_join(renderer->worker_thread, NULL); + + pthread_mutex_destroy(&renderer->mutex); + pthread_cond_destroy(&renderer->cond); +} + +void +renderer_set_surface_queue(struct tinyds_renderer *renderer, + void *surface_queue) +{ + pthread_mutex_lock(&renderer->mutex); + + renderer->surface_queue = (tbm_surface_queue_h)surface_queue; + + pthread_mutex_unlock(&renderer->mutex); +} + +void +renderer_set_bg_color(struct tinyds_renderer *renderer, + uint8_t r, uint8_t g, uint8_t b) +{ + pixman_color_t color; + + pthread_mutex_lock(&renderer->mutex); + + color_rgb888(&color, r, g, b); + + renderer->bg_image = pixman_image_create_solid_fill(&color); + assert(renderer->bg_image); + + renderer->damaged = true; + + pthread_mutex_unlock(&renderer->mutex); +} + +void +renderer_add_texture(struct tinyds_renderer *renderer, + tbm_surface_h tbm_surface, int x, int y) +{ + struct tinyds_texture *texture; + + pthread_mutex_lock(&renderer->mutex); + + texture = calloc(1, sizeof *texture); + + texture->x = x; + texture->y = y; + texture->renderer = renderer; + texture->surface = tbm_surface; + texture->image = pixman_image_from_tbm_surface(tbm_surface, + DS_BUFFER_DATA_PTR_ACCESS_READ); + + wl_list_insert(renderer->textures.prev, &texture->link); + + ds_dbg("Add texture(%p)", texture); + + pthread_mutex_unlock(&renderer->mutex); +} + +void +renderer_draw(struct tinyds_renderer *renderer) +{ + pthread_mutex_lock(&renderer->mutex); + + renderer->damaged = true; + pthread_cond_signal(&renderer->cond); + + pthread_mutex_unlock(&renderer->mutex); +} + +static void +renderer_setup_thread(struct tinyds_renderer *renderer) +{ + pthread_mutex_init(&renderer->mutex, NULL); + pthread_cond_init(&renderer->cond, NULL); + pthread_create(&renderer->worker_thread, NULL, + renderer_thread_func, renderer); +} + +static void * +renderer_thread_func(void *data) +{ + struct tinyds_renderer *renderer = data; + struct tinyds_texture *texture, *texture_tmp; + pixman_image_t *dst_image; + tbm_surface_h surface; + tbm_surface_queue_error_e err; + + pthread_mutex_lock(&renderer->mutex); + + while (!renderer->destroying) { + if (!renderer->damaged) + pthread_cond_wait(&renderer->cond, &renderer->mutex); + + if (!renderer->damaged) + continue; + + if (!tbm_surface_queue_can_dequeue(renderer->surface_queue, 0)) + continue; + + ds_dbg(">> BEGIN DRAW"); + + err = tbm_surface_queue_dequeue(renderer->surface_queue, &surface); + assert(err == TBM_SURFACE_QUEUE_ERROR_NONE); + + dst_image = pixman_image_from_tbm_surface(surface, + DS_BUFFER_DATA_PTR_ACCESS_WRITE); + + if (renderer->bg_image) { + pixman_image_composite32(PIXMAN_OP_SRC, + renderer->bg_image, + NULL, + dst_image, + 0, 0, 0, 0, 0, 0, + pixman_image_get_width(dst_image), + pixman_image_get_height(dst_image)); + } + + wl_list_for_each_safe(texture, texture_tmp, &renderer->textures, link) { + ds_dbg("Draw texture(%p)", texture); + pixman_image_composite32(PIXMAN_OP_OVER, + texture->image, + NULL, + dst_image, + 0, 0, 0, 0, + texture->x, texture->y, + pixman_image_get_width(texture->image), + pixman_image_get_height(texture->image)); + texture_destroy(texture); + } + pixman_image_unref(dst_image); + + err = tbm_surface_queue_enqueue(renderer->surface_queue, surface); + assert(err == TBM_SURFACE_QUEUE_ERROR_NONE); + + renderer->damaged = false; + + ds_dbg("<< END DRAW"); + } + + pthread_mutex_unlock(&renderer->mutex); + + return NULL; +} + +static void +texture_destroy(struct tinyds_texture *texture) +{ + pixman_image_unref(texture->image); + wl_list_remove(&texture->link); + free(texture); +} diff --git a/src/examples/tinyds-tdm-renderer.h b/src/examples/tinyds-tdm-renderer.h new file mode 100644 index 0000000..5f3e6fd --- /dev/null +++ b/src/examples/tinyds-tdm-renderer.h @@ -0,0 +1,48 @@ +#ifndef EXAMPLES_TINYDS_TDM_RENDERER_H +#define EXAMPLES_TINYDS_TDM_RENDERER_H + +#include +#include +#include +#include +#include + +struct tinyds_renderer +{ + tbm_surface_queue_h surface_queue; + + struct wl_list textures; + + pthread_t worker_thread; + pthread_mutex_t mutex; + pthread_cond_t cond; + + pixman_image_t *bg_image; + + bool damaged; + bool destroying; +}; + +struct tinyds_texture +{ + struct tinyds_renderer *renderer; + pixman_image_t *image; + tbm_surface_h surface; + + struct wl_list link; + struct wl_listener buffer_destroy; + + int x, y; +}; + +bool init_renderer(struct tinyds_renderer *renderer); +void fini_renderer(struct tinyds_renderer *renderer); +void renderer_set_surface_queue(struct tinyds_renderer *renderer, + void *surface_queue); +void renderer_set_bg_color(struct tinyds_renderer *renderer, + uint8_t r, uint8_t g, uint8_t b); +void renderer_add_texture(struct tinyds_renderer *renderer, + tbm_surface_h tbm_surface, int x, int y); +void renderer_draw(struct tinyds_renderer *renderer); + +#endif diff --git a/src/examples/tinyds-tdm.c b/src/examples/tinyds-tdm.c index 143d53e..6ec1156 100644 --- a/src/examples/tinyds-tdm.c +++ b/src/examples/tinyds-tdm.c @@ -1,6 +1,3 @@ -#include "tbm-server-helper.h" -#include "pixman-helper.h" - #include #include #include @@ -14,12 +11,23 @@ #include #include #include -#include #include #include #include #include +#define USE_TDM_BUFFER_QUEUE + +#ifdef USE_TDM_BUFFER_QUEUE +#include "pixman-tbm-helper.h" +#include "tinyds-tdm-renderer.h" +#else +#include +#endif + +#include "tbm-server-helper.h" +#include "pixman-helper.h" + #define TINYDS_UNUSED __attribute__((unused)) struct tinyds_output @@ -27,7 +35,13 @@ struct tinyds_output struct tinyds_server *server; struct ds_output *ds_output; struct ds_allocator *allocator; +#ifdef USE_TDM_BUFFER_QUEUE + struct tinyds_renderer renderer; + struct ds_tdm_buffer_queue *buffer_queue; + struct wl_listener buffer_queue_acquirable; +#else struct ds_swapchain *swapchain; +#endif struct ds_buffer *front_buffer; struct wl_listener output_destroy; @@ -62,6 +76,7 @@ struct tinyds_view { struct tinyds_server *server; + struct tinyds_texture *texture; struct ds_xdg_surface *xdg_surface; struct wl_listener xdg_surface_map; @@ -82,7 +97,18 @@ static void output_handle_destroy(struct wl_listener *listener, void *data); static void output_handle_frame(struct wl_listener *listener, void *data); static void draw_server_with_damage(struct tinyds_server *server); static void draw_output(struct tinyds_output *output); +static void output_swap_buffer(struct tinyds_output *output, + struct ds_buffer *buffer); +static void view_send_frame_done(struct tinyds_view *view); +#ifdef USE_TDM_BUFFER_QUEUE +static void output_buffer_queue_init(struct tinyds_output *output); +static void output_renderer_init(struct tinyds_output *output); +static void output_draw_with_renderer(struct tinyds_output *output); +#else +static void output_swapchain_init(struct tinyds_output *output); +static void output_draw_with_swapchain(struct tinyds_output *output); static void draw_view(struct tinyds_view *view, pixman_image_t *dst_image); +#endif int main(void) @@ -150,10 +176,10 @@ view_handle_xdg_surface_destroy(struct wl_listener *listener, void *data TINYDS_UNUSED) { struct tinyds_view *view; + struct tinyds_server *server; view = wl_container_of(listener, view, xdg_surface_destroy); - - draw_server_with_damage(view->server); + server = view->server; wl_list_remove(&view->xdg_surface_destroy.link); wl_list_remove(&view->xdg_surface_map.link); @@ -161,6 +187,8 @@ view_handle_xdg_surface_destroy(struct wl_listener *listener, wl_list_remove(&view->surface_commit.link); wl_list_remove(&view->link); free(view); + + draw_server_with_damage(server); } static void @@ -237,32 +265,25 @@ backend_handle_new_output(struct wl_listener *listener, void *data) if (!output) return; - output->allocator = ds_tbm_allocator_create(); - if (!output->allocator) { - free(output); - return; - } - - output->swapchain = ds_swapchain_create(output->allocator, - mode->width, mode->height, DRM_FORMAT_XRGB8888); - if (!output->swapchain) { - ds_allocator_destroy(output->allocator); - free(output); - return; - } - output->server = server; output->ds_output = ds_output; + output->width = mode->width; + output->height = mode->height; output->drawable = true; output->damaged = true; +#ifdef USE_TDM_BUFFER_QUEUE + output_buffer_queue_init(output); + output_renderer_init(output); +#else + output_swapchain_init(output); +#endif + output->output_destroy.notify = output_handle_destroy; - ds_output_add_destroy_listener(ds_output, - &output->output_destroy); + ds_output_add_destroy_listener(ds_output, &output->output_destroy); output->output_frame.notify = output_handle_frame; - ds_output_add_frame_listener(ds_output, - &output->output_frame); + ds_output_add_frame_listener(ds_output, &output->output_frame); server->output = output; @@ -318,11 +339,15 @@ output_handle_destroy(struct wl_listener *listener, void *data TINYDS_UNUSED) if (output->front_buffer) ds_buffer_unlock(output->front_buffer); +#ifdef USE_TDM_BUFFER_QUEUE + fini_renderer(&output->renderer); +#else if (output->swapchain) ds_swapchain_destroy(output->swapchain); if (output->allocator) ds_allocator_destroy(output->allocator); +#endif wl_display_terminate(output->server->display); @@ -348,15 +373,102 @@ draw_server_with_damage(struct tinyds_server *server) draw_output(server->output); } +#ifdef USE_TDM_BUFFER_QUEUE static void -draw_output(struct tinyds_output *output) +output_handle_buffer_queue_acquirable(struct wl_listener *listener, + void *data TINYDS_UNUSED) +{ + struct tinyds_output *output; + struct ds_buffer *buffer; + + output = wl_container_of(listener, output, buffer_queue_acquirable); + + buffer = ds_tdm_buffer_queue_acquire(output->buffer_queue); + assert(buffer); + + output_swap_buffer(output, buffer); +} + +static void +output_buffer_queue_init(struct tinyds_output *output) +{ + struct ds_tdm_output *tdm_output; + + tdm_output = ds_tdm_output_from_output(output->ds_output); + assert(tdm_output); + + output->buffer_queue = ds_tdm_output_get_buffer_queue(tdm_output); + assert(output->buffer_queue); + + output->buffer_queue_acquirable.notify = + output_handle_buffer_queue_acquirable; + ds_tdm_buffer_queue_add_acquirable_listener(output->buffer_queue, + &output->buffer_queue_acquirable); +} + +static void +output_renderer_init(struct tinyds_output *output) +{ + init_renderer(&output->renderer); + + renderer_set_surface_queue(&output->renderer, + ds_tdm_buffer_queue_get_native_queue(output->buffer_queue)); + + renderer_set_bg_color(&output->renderer, 80, 80, 80); +} + +static void +output_draw_with_renderer(struct tinyds_output *output) { - struct ds_buffer *output_buffer; - pixman_image_t *output_image; struct tinyds_view *view; - if (!output->drawable || !output->damaged) - return; + ds_dbg(">> BEGIN UPDATE TEXTURES"); + + wl_list_for_each(view, &output->server->views, link) { + struct ds_buffer *ds_buffer; + struct tbm_client_buffer *buffer; + tbm_surface_h surface; + + if (!view->mapped) + continue; + + ds_buffer = ds_surface_get_buffer( + ds_xdg_surface_get_surface(view->xdg_surface)); + assert(buffer); + + buffer = tbm_client_buffer_from_buffer(ds_buffer); + assert(buffer); + + surface = tbm_client_buffer_get_tbm_surface(buffer); + + renderer_add_texture(&output->renderer, surface, view->x, view->y); + + view_send_frame_done(view); + } + + ds_dbg("<< END UPDATE TEXTURES"); + + renderer_draw(&output->renderer); + +} +#else +static void +output_swapchain_init(struct tinyds_output *output) +{ + output->allocator = ds_tbm_allocator_create(); + assert(output->allocator); + + output->swapchain = ds_swapchain_create(output->allocator, + mode->width, mode->height, DRM_FORMAT_XRGB8888); + assert(output->swapchain); +} + +static void +output_draw_with_swapchain(struct tinyds_output *output) +{ + struct tinyds_view *view; + struct ds_buffer *output_buffer; + pixman_image_t *output_image; output_buffer = ds_swapchain_acquire(output->swapchain, NULL); if (!output_buffer) @@ -378,24 +490,7 @@ draw_output(struct tinyds_output *output) } pixman_image_unref(output_image); - ds_output_attach_buffer(output->ds_output, output_buffer); - ds_output_commit(output->ds_output); - - if (output->front_buffer) - ds_buffer_unlock(output->front_buffer); - output->front_buffer = output_buffer; - - output->drawable = false; - output->damaged = false; -} - -static void -view_send_frame_done(struct tinyds_view *view) -{ - struct timespec now; - clock_gettime(CLOCK_MONOTONIC, &now); - ds_surface_send_frame_done(ds_xdg_surface_get_surface(view->xdg_surface), - &now); + output_swap_buffer(output, output_buffer); } static void @@ -423,6 +518,44 @@ draw_view(struct tinyds_view *view, pixman_image_t *dst_image) view_send_frame_done(view); } +#endif + +static void +draw_output(struct tinyds_output *output) +{ + + if (!output->drawable || !output->damaged) + return; + +#ifdef USE_TDM_BUFFER_QUEUE + output_draw_with_renderer(output); +#else + output_draw_with_swapchain(output); +#endif + + output->drawable = false; + output->damaged = false; +} + +static void +output_swap_buffer(struct tinyds_output *output, struct ds_buffer *buffer) +{ + ds_output_attach_buffer(output->ds_output, buffer); + ds_output_commit(output->ds_output); + + if (output->front_buffer) + ds_buffer_unlock(output->front_buffer); + output->front_buffer = buffer; +} + +static void +view_send_frame_done(struct tinyds_view *view) +{ + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + ds_surface_send_frame_done(ds_xdg_surface_get_surface(view->xdg_surface), + &now); +} static int server_dispatch_stdin(int fd, uint32_t mask, void *data) -- 2.7.4 From 43c51b3bee4ee7bf17cdba0cff235ebb21554234 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Thu, 17 Mar 2022 19:52:29 +0900 Subject: [PATCH 13/16] Fix typo on a word of header guard Change-Id: Ie18d91a7868efa6b13175693d4f9a99c2481d09e --- src/libds-tizen/backend/tdm/tdm_buffer_queue.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libds-tizen/backend/tdm/tdm_buffer_queue.h b/src/libds-tizen/backend/tdm/tdm_buffer_queue.h index 774b7c3..a983265 100644 --- a/src/libds-tizen/backend/tdm/tdm_buffer_queue.h +++ b/src/libds-tizen/backend/tdm/tdm_buffer_queue.h @@ -1,5 +1,5 @@ #ifndef DS_TIZEN_BACKEND_TDM_BUFFER_QUEUE_H -#define DS_TIZEN_BACKEND_TBM_BUFFER_QUEUE_H +#define DS_TIZEN_BACKEND_TDM_BUFFER_QUEUE_H #include #include -- 2.7.4 From 3009fac9ea49a2ed4b041128a259e6e47a1ca275 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Mon, 28 Mar 2022 20:03:20 +0900 Subject: [PATCH 14/16] Add ds_tbm_server ds_tbm_server initializes wayland_tbm to allow wl_client to use tbm_surface as a wl_buffer. Change-Id: Ic3a450b6d450bad94388eeca5e9433b5dc799513 --- include/libds-tizen/tbm_server.h | 24 +++ src/examples/meson.build | 6 +- src/examples/tbm-server-helper.h | 41 ----- src/examples/tinyds-tdm.c | 23 ++- src/libds-tizen/meson.build | 8 +- src/libds-tizen/pixel_format.c | 61 ++++++ src/libds-tizen/pixel_format.h | 10 + .../tbm_server.c} | 204 ++++++++++++--------- src/libds-tizen/tbm_server.h | 34 ++++ 9 files changed, 272 insertions(+), 139 deletions(-) create mode 100644 include/libds-tizen/tbm_server.h delete mode 100644 src/examples/tbm-server-helper.h create mode 100644 src/libds-tizen/pixel_format.c create mode 100644 src/libds-tizen/pixel_format.h rename src/{examples/tbm-server-helper.c => libds-tizen/tbm_server.c} (66%) create mode 100644 src/libds-tizen/tbm_server.h diff --git a/include/libds-tizen/tbm_server.h b/include/libds-tizen/tbm_server.h new file mode 100644 index 0000000..c48977e --- /dev/null +++ b/include/libds-tizen/tbm_server.h @@ -0,0 +1,24 @@ +#ifndef LIBDS_TIZEN_TBM_SERVER_H +#define LIBDS_TIZEN_TBM_SERVER_H + +#include +#include + +struct ds_tbm_server; + +struct ds_tbm_client_buffer; + +struct ds_tbm_server * +ds_tbm_server_create(struct wl_display *display); + +void +ds_tbm_server_add_destroy_listener(struct ds_tbm_server *tbm, + struct wl_listener *listener); + +struct ds_tbm_client_buffer * +ds_tbm_client_buffer_from_buffer(struct ds_buffer *ds_buffer); + +tbm_surface_h +ds_tbm_client_buffer_get_tbm_surface(struct ds_tbm_client_buffer *buffer); + +#endif diff --git a/src/examples/meson.build b/src/examples/meson.build index c60b610..ddb0792 100644 --- a/src/examples/meson.build +++ b/src/examples/meson.build @@ -35,19 +35,15 @@ if get_option('tizen') tinyds_tdm_files = [ 'tinyds-tdm.c', - 'tinyds-tdm-renderer.c', - 'tbm-server-helper.c', 'pixman-helper.c', 'pixman-tbm-helper.c', + 'tinyds-tdm-renderer.c', ] executable('tinyds-tdm', tinyds_tdm_files, dependencies: [ common_deps, dependency('pixman-1', required: true), - dependency('libdrm', required: true), - dependency('libtbm', required: true), - dependency('wayland-tbm-server', required: true), dependency('threads', required: true), ], install_dir: libds_bindir, diff --git a/src/examples/tbm-server-helper.h b/src/examples/tbm-server-helper.h deleted file mode 100644 index 609f370..0000000 --- a/src/examples/tbm-server-helper.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef EXAMPLES_TBM_SERVER_H -#define EXAMPLES_TBM_SERVER_H - -#include -#include -#include -#include -#include - -struct tbm_server -{ - struct wayland_tbm_server *wl_tbm; - - struct wl_listener display_destroy; -}; - -struct tbm_client_buffer -{ - struct ds_buffer base; - - tbm_surface_h surface; - struct wl_resource *resource; - - struct wl_listener buffer_release; - struct wl_listener resource_destroy; - - uint32_t format; - size_t stride; -}; - -bool -tbm_server_init_display(struct tbm_server *tbm_server, - struct wl_display *display); - -struct tbm_client_buffer * -tbm_client_buffer_from_buffer(struct ds_buffer *ds_buffer); - -tbm_surface_h -tbm_client_buffer_get_tbm_surface(struct tbm_client_buffer *buffer); - -#endif diff --git a/src/examples/tinyds-tdm.c b/src/examples/tinyds-tdm.c index 6ec1156..c14cb9e 100644 --- a/src/examples/tinyds-tdm.c +++ b/src/examples/tinyds-tdm.c @@ -15,6 +15,7 @@ #include #include #include +#include #define USE_TDM_BUFFER_QUEUE @@ -25,7 +26,6 @@ #include #endif -#include "tbm-server-helper.h" #include "pixman-helper.h" #define TINYDS_UNUSED __attribute__((unused)) @@ -55,7 +55,7 @@ struct tinyds_output struct tinyds_server { - struct tbm_server tbm_server; + struct ds_tbm_server *tbm_server; struct wl_display *display; @@ -127,9 +127,6 @@ main(void) res = init_server(server, display); assert(res); - res = tbm_server_init_display(&server->tbm_server, display); - assert(res); - socket = wl_display_add_socket_auto(display); assert(socket); @@ -314,6 +311,12 @@ init_server(struct tinyds_server *server, struct wl_display *display) return false; } + server->tbm_server = ds_tbm_server_create(display); + if (!server->tbm_server) { + ds_backend_destroy(server->backend); + return false; + } + server->xdg_shell = ds_xdg_shell_create(display); if (!server->xdg_shell) { ds_backend_destroy(server->backend); @@ -426,7 +429,7 @@ output_draw_with_renderer(struct tinyds_output *output) wl_list_for_each(view, &output->server->views, link) { struct ds_buffer *ds_buffer; - struct tbm_client_buffer *buffer; + struct ds_tbm_client_buffer *tbm_buffer; tbm_surface_h surface; if (!view->mapped) @@ -434,12 +437,12 @@ output_draw_with_renderer(struct tinyds_output *output) ds_buffer = ds_surface_get_buffer( ds_xdg_surface_get_surface(view->xdg_surface)); - assert(buffer); + assert(ds_buffer); - buffer = tbm_client_buffer_from_buffer(ds_buffer); - assert(buffer); + tbm_buffer = ds_tbm_client_buffer_from_buffer(ds_buffer); + assert(tbm_buffer); - surface = tbm_client_buffer_get_tbm_surface(buffer); + surface = ds_tbm_client_buffer_get_tbm_surface(tbm_buffer); renderer_add_texture(&output->renderer, surface, view->x, view->y); diff --git a/src/libds-tizen/meson.build b/src/libds-tizen/meson.build index e9ca734..4f76b68 100644 --- a/src/libds-tizen/meson.build +++ b/src/libds-tizen/meson.build @@ -1,7 +1,13 @@ -libds_tizen_files = [] +libds_tizen_files = [ + 'pixel_format.c', + 'tbm_server.c', +] libds_tizen_deps = [ dep_libds, + dependency('libdrm', required: true), + dependency('libtbm', required: true), + dependency('wayland-tbm-server', required: true), ] subdir('allocator') diff --git a/src/libds-tizen/pixel_format.c b/src/libds-tizen/pixel_format.c new file mode 100644 index 0000000..021652e --- /dev/null +++ b/src/libds-tizen/pixel_format.c @@ -0,0 +1,61 @@ +#include +#include +#include + +#include "libds/log.h" +#include "pixel_format.h" + +#ifdef ARRAY_LENGTH +#undef ARRAY_LENGTH +#endif + +#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0]) + +struct ds_tbm_format +{ + uint32_t drm_format; + uint32_t tbm_format; +}; + +static const struct ds_tbm_format formats[] = +{ + { + .drm_format = DRM_FORMAT_ARGB8888, + .tbm_format = TBM_FORMAT_ARGB8888, + }, + { + .drm_format = DRM_FORMAT_XRGB8888, + .tbm_format = TBM_FORMAT_XRGB8888, + }, + /* TODO more format */ +}; + +uint32_t +convert_drm_format_to_tbm(uint32_t fmt) +{ + size_t i; + + for (i = 0; i < ARRAY_LENGTH(formats); i++) { + if (formats[i].drm_format == fmt) + return formats[i].tbm_format; + } + + ds_err("DRM format 0x%"PRIX32" has no TBM equivalent", fmt); + + return 0; +} + +uint32_t +convert_tbm_format_to_drm(uint32_t fmt) +{ + size_t i; + + for (i = 0; i < ARRAY_LENGTH(formats); i++) { + if (formats[i].tbm_format == fmt) + return formats[i].drm_format; + } + + ds_err("TBM format 0x%"PRIX32" has no DRM equivalent", fmt); + + return 0; +} diff --git a/src/libds-tizen/pixel_format.h b/src/libds-tizen/pixel_format.h new file mode 100644 index 0000000..a63d096 --- /dev/null +++ b/src/libds-tizen/pixel_format.h @@ -0,0 +1,10 @@ +#ifndef DS_TIZEN_PIXEL_FORMAT_H +#define DS_TIZEN_PIXEL_FORMAT_H + +#include + +uint32_t convert_drm_format_to_tbm(uint32_t fmt); + +uint32_t convert_tbm_format_to_drm(uint32_t fmt); + +#endif diff --git a/src/examples/tbm-server-helper.c b/src/libds-tizen/tbm_server.c similarity index 66% rename from src/examples/tbm-server-helper.c rename to src/libds-tizen/tbm_server.c index 320ee4f..ecb46db 100644 --- a/src/examples/tbm-server-helper.c +++ b/src/libds-tizen/tbm_server.c @@ -1,82 +1,111 @@ -#include "tbm-server-helper.h" - #include #include #include -#include + #include -#include + +#include "libds/log.h" +#include "pixel_format.h" +#include "tbm_server.h" static const struct ds_buffer_resource_interface tbm_buffer_resource_iface; static const struct ds_buffer_interface tbm_client_buffer_iface; static void tbm_server_handle_display_destroy(struct wl_listener *listener, void *data); -static struct tbm_client_buffer * -tbm_client_buffer_create(struct wl_resource *resource); -bool -tbm_server_init_display(struct tbm_server *tbm, struct wl_display *display) +WL_EXPORT struct ds_tbm_server * +ds_tbm_server_create(struct wl_display *display) { + struct ds_tbm_server *tbm; tbm_bufmgr bufmgr; + tbm = calloc(1, sizeof *tbm); + if (!tbm) + return NULL; + + wl_signal_init(&tbm->events.destroy); + tbm->wl_tbm = wayland_tbm_server_init(display, NULL, -1, 0); if (!tbm->wl_tbm) { - return false; + goto err_wl_tbm; } bufmgr = wayland_tbm_server_get_bufmgr(tbm->wl_tbm); if (!bufmgr) { - wayland_tbm_server_deinit(tbm->wl_tbm); - return false; + goto err_bind; } if (!tbm_bufmgr_bind_native_display(bufmgr, (void *)display)) { - wayland_tbm_server_deinit(tbm->wl_tbm); - return false; + goto err_bind; } - ds_buffer_register_resource_interface(&tbm_buffer_resource_iface); - tbm->display_destroy.notify = tbm_server_handle_display_destroy; wl_display_add_destroy_listener(display, &tbm->display_destroy); - return true; + ds_buffer_register_resource_interface(&tbm_buffer_resource_iface); + + return tbm; + +err_bind: + wayland_tbm_server_deinit(tbm->wl_tbm); +err_wl_tbm: + free(tbm); + + return NULL; } -struct tbm_client_buffer * -tbm_client_buffer_from_buffer(struct ds_buffer *ds_buffer) +WL_EXPORT void +ds_tbm_server_add_destroy_listener(struct ds_tbm_server *tbm, + struct wl_listener *listener) { - assert(ds_buffer->iface == &tbm_client_buffer_iface); - return (struct tbm_client_buffer *)ds_buffer; + wl_signal_add(&tbm->events.destroy, listener); +} + +WL_EXPORT struct ds_tbm_client_buffer * +ds_tbm_client_buffer_from_buffer(struct ds_buffer *ds_buffer) +{ + if (ds_buffer->iface != &tbm_client_buffer_iface) + return NULL; + return (struct ds_tbm_client_buffer *)ds_buffer; } -tbm_surface_h -tbm_client_buffer_get_tbm_surface(struct tbm_client_buffer *buffer) +WL_EXPORT tbm_surface_h +ds_tbm_client_buffer_get_tbm_surface(struct ds_tbm_client_buffer *buffer) { + if (buffer->base.iface != &tbm_client_buffer_iface) + return NULL; return buffer->surface; } static void tbm_server_handle_display_destroy(struct wl_listener *listener, void *data) { - struct tbm_server *tbm; + struct ds_tbm_server *tbm; tbm = wl_container_of(listener, tbm, display_destroy); + + wl_signal_emit(&tbm->events.destroy, tbm); + wayland_tbm_server_deinit(tbm->wl_tbm); + free(tbm); } -static bool -tbm_buffer_resource_iface_is_instance(struct wl_resource *resource) +static void +tbm_client_buffer_handle_release(struct wl_listener *listener, void *data) { - return !!wayland_tbm_server_get_surface(NULL, resource); + struct ds_tbm_client_buffer *buffer; + + buffer = wl_container_of(listener, buffer, buffer_release); + if (buffer->resource) + wl_buffer_send_release(buffer->resource); } static void tbm_client_buffer_handle_resource_destroy(struct wl_listener *listener, void *data) { - struct tbm_client_buffer *buffer; + struct ds_tbm_client_buffer *buffer; buffer = wl_container_of(listener, buffer, resource_destroy); @@ -88,44 +117,17 @@ tbm_client_buffer_handle_resource_destroy(struct wl_listener *listener, ds_buffer_drop(&buffer->base); } -static struct tbm_client_buffer * -tbm_client_buffer_get_or_create(struct wl_resource *resource) -{ - struct tbm_client_buffer *buffer; - struct wl_listener *resource_destroy_listener; - - resource_destroy_listener = wl_resource_get_destroy_listener(resource, - tbm_client_buffer_handle_resource_destroy);; - if (resource_destroy_listener) { - buffer = wl_container_of(resource_destroy_listener, - buffer, resource_destroy); - return buffer; - } - - return tbm_client_buffer_create(resource); -} - -static struct ds_buffer * -tbm_buffer_resource_iface_from_resource(struct wl_resource *resource) +static struct ds_tbm_client_buffer * +tbm_client_buffer_from_buffer(struct ds_buffer *ds_buffer) { - struct tbm_client_buffer *buffer; - - buffer = tbm_client_buffer_get_or_create(resource); - assert(buffer); - - return &buffer->base; + assert(ds_buffer->iface == &tbm_client_buffer_iface); + return (struct ds_tbm_client_buffer *)ds_buffer; } -static const struct ds_buffer_resource_interface tbm_buffer_resource_iface = { - .name = "tbm", - .is_instance = tbm_buffer_resource_iface_is_instance, - .from_resource = tbm_buffer_resource_iface_from_resource, -}; - static void -tbm_client_buffer_destroy(struct ds_buffer *ds_buffer) +tbm_client_buffer_iface_destroy(struct ds_buffer *ds_buffer) { - struct tbm_client_buffer *buffer; + struct ds_tbm_client_buffer *buffer; buffer = tbm_client_buffer_from_buffer(ds_buffer); @@ -137,11 +139,11 @@ tbm_client_buffer_destroy(struct ds_buffer *ds_buffer) } static bool -tbm_client_buffer_begin_data_ptr_access(struct ds_buffer *ds_buffer, +tbm_client_buffer_iface_begin_data_ptr_access(struct ds_buffer *ds_buffer, enum ds_buffer_data_ptr_access_flag flags, void **data, uint32_t *format, size_t *stride) { - struct tbm_client_buffer *buffer; + struct ds_tbm_client_buffer *buffer; tbm_surface_info_s info; tbm_bo_access_option op = TBM_OPTION_NONE; int err; @@ -160,7 +162,7 @@ tbm_client_buffer_begin_data_ptr_access(struct ds_buffer *ds_buffer, return false; } - *format = DRM_FORMAT_XRGB8888; // FIXME + *format = convert_tbm_format_to_drm(buffer->format); *stride = info.planes[0].stride; *data = info.planes[0].ptr; @@ -168,9 +170,9 @@ tbm_client_buffer_begin_data_ptr_access(struct ds_buffer *ds_buffer, } static void -tbm_client_buffer_end_data_ptr_access(struct ds_buffer *ds_buffer) +tbm_client_buffer_iface_end_ptr_access(struct ds_buffer *ds_buffer) { - struct tbm_client_buffer *buffer; + struct ds_tbm_client_buffer *buffer; buffer = tbm_client_buffer_from_buffer(ds_buffer); @@ -178,36 +180,31 @@ tbm_client_buffer_end_data_ptr_access(struct ds_buffer *ds_buffer) } static const struct ds_buffer_interface tbm_client_buffer_iface = { - .destroy = tbm_client_buffer_destroy, - .begin_data_ptr_access = tbm_client_buffer_begin_data_ptr_access, - .end_data_ptr_access = tbm_client_buffer_end_data_ptr_access, + .destroy = tbm_client_buffer_iface_destroy, + .begin_data_ptr_access = tbm_client_buffer_iface_begin_data_ptr_access, + .end_data_ptr_access = tbm_client_buffer_iface_end_ptr_access, }; -static void -tbm_client_buffer_handle_release(struct wl_listener *listener, void *data) -{ - struct tbm_client_buffer *buffer; - - buffer = wl_container_of(listener, buffer, buffer_release); - if (buffer->resource) - wl_buffer_send_release(buffer->resource); -} - -static struct tbm_client_buffer * +static struct ds_tbm_client_buffer * tbm_client_buffer_create(struct wl_resource *resource) { - struct tbm_client_buffer *buffer; + struct ds_tbm_client_buffer *buffer; tbm_surface_h surface; int32_t width, height; surface = wayland_tbm_server_get_surface(NULL, resource); - assert(surface); + if (!surface) { + ds_err("Could not get tbm_surface from wl_resource@%d", + wl_resource_get_id(resource)); + return NULL; + } width = tbm_surface_get_width(surface); height = tbm_surface_get_height(surface); buffer = calloc(1, sizeof *buffer); - assert(buffer); + if (!buffer) + return NULL; ds_buffer_init(&buffer->base, &tbm_client_buffer_iface, width, height); @@ -226,3 +223,46 @@ tbm_client_buffer_create(struct wl_resource *resource) return buffer; } + +static struct ds_tbm_client_buffer * +tbm_client_buffer_get_or_create(struct wl_resource *resource) +{ + struct ds_tbm_client_buffer *buffer; + struct wl_listener *resource_destroy_listener; + + resource_destroy_listener = wl_resource_get_destroy_listener(resource, + tbm_client_buffer_handle_resource_destroy);; + if (resource_destroy_listener) { + buffer = wl_container_of(resource_destroy_listener, + buffer, resource_destroy); + return buffer; + } + + return tbm_client_buffer_create(resource); +} + +static bool +tbm_buffer_resource_iface_is_instance(struct wl_resource *resource) +{ + return !!wayland_tbm_server_get_surface(NULL, resource); +} + +static struct ds_buffer * +tbm_buffer_resource_iface_from_resource(struct wl_resource *resource) +{ + struct ds_tbm_client_buffer *buffer; + + buffer = tbm_client_buffer_get_or_create(resource); + if (!buffer) { + ds_err("Could not get or create ds_tbm_client_buffer"); + return NULL; + } + + return &buffer->base; +} + +static const struct ds_buffer_resource_interface tbm_buffer_resource_iface = { + .name = "tbm", + .is_instance = tbm_buffer_resource_iface_is_instance, + .from_resource = tbm_buffer_resource_iface_from_resource, +}; diff --git a/src/libds-tizen/tbm_server.h b/src/libds-tizen/tbm_server.h new file mode 100644 index 0000000..be56746 --- /dev/null +++ b/src/libds-tizen/tbm_server.h @@ -0,0 +1,34 @@ +#ifndef DS_TIZEN_TBM_SERVER_H +#define DS_TIZEN_TBM_SERVER_H + +#include +#include +#include +#include "libds/interfaces/buffer.h" + +struct ds_tbm_server +{ + struct wayland_tbm_server *wl_tbm; + + struct wl_listener display_destroy; + + struct { + struct wl_signal destroy; + } events; +}; + +struct ds_tbm_client_buffer +{ + struct ds_buffer base; + + tbm_surface_h surface; + struct wl_resource *resource; + + struct wl_listener buffer_release; + struct wl_listener resource_destroy; + + uint32_t format; + size_t stride; +}; + +#endif -- 2.7.4 From de85e1d57eb3b1ec7f8ff04a877b335ea99bca54 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Wed, 30 Mar 2022 16:44:45 +0900 Subject: [PATCH 15/16] add extern 'C' at tbm_server.h Change-Id: Ida5b0215bcfd753f124c9b3d3102caeb881f5160 --- include/libds-tizen/tbm_server.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/libds-tizen/tbm_server.h b/include/libds-tizen/tbm_server.h index c48977e..f1cc97d 100644 --- a/include/libds-tizen/tbm_server.h +++ b/include/libds-tizen/tbm_server.h @@ -4,6 +4,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + struct ds_tbm_server; struct ds_tbm_client_buffer; @@ -21,4 +25,8 @@ ds_tbm_client_buffer_from_buffer(struct ds_buffer *ds_buffer); tbm_surface_h ds_tbm_client_buffer_get_tbm_surface(struct ds_tbm_client_buffer *buffer); +#ifdef __cplusplus +} +#endif + #endif -- 2.7.4 From 6e6592802e7dbc90538876e5ecb612e6906aafa4 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Wed, 30 Mar 2022 19:57:41 +0900 Subject: [PATCH 16/16] add ws_members as reviewers Change-Id: I6e027ad8496c66d91de0edfa5cd9a9c8ed2bb712 --- CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODEOWNERS b/CODEOWNERS index 2c7fc6d..b37075e 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -5,5 +5,5 @@ # the repo. Unless a later match takes precedence, # @global-owner1 and @global-owner2 will be requested for # review when someone opens a pull request. -* @doyoun-kang @gl77-lee @sc1-lim @shiin-lee +* @TizenWS/ws_members -- 2.7.4