From ed5099f54173a885b85e81bcf950f5fc1ba2ba2c Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Wed, 2 Mar 2022 11:36:44 +0900 Subject: [PATCH 01/16] Add build options of backends Change-Id: I344dd28196280c91f4c3fa064bc60f5a439b3fa2 --- examples/meson.build | 34 ++++++++++++++++++---------------- include/meson.build | 12 +++++++++++- meson.build | 12 +++++------- meson_options.txt | 1 + src/libds/{allocator => }/allocator.c | 0 src/libds/allocator/meson.build | 12 ++++++++++++ src/libds/backend/meson.build | 15 ++++++++++++++- src/libds/backend/tdm/meson.build | 26 +++++++++++++++++++++++++- src/libds/meson.build | 21 +++++++++++++++++---- 9 files changed, 103 insertions(+), 30 deletions(-) create mode 100644 meson_options.txt rename src/libds/{allocator => }/allocator.c (100%) create mode 100644 src/libds/allocator/meson.build diff --git a/examples/meson.build b/examples/meson.build index 54f1ba7..66336f5 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -9,12 +9,6 @@ executable('wl-backend', install_dir: libds_bindir, install : true) -executable('tdm-backend', - 'tdm-backend.c', - dependencies: common_deps, - install_dir: libds_bindir, - install : true) - executable('tinyds', 'tinyds.c', dependencies: [ @@ -25,13 +19,21 @@ executable('tinyds', install_dir: libds_bindir, install : true) -executable('tinyds-tdm', - ['tinyds-tdm.c', 'tinyds-helper.c'], - dependencies: [ - common_deps, - dependency('pixman-1', required: true), - dependency('libdrm', required: true), - dependency('libtbm', required: true), - ], - install_dir: libds_bindir, - install : true) +if features.get('tdm-backend') + executable('tdm-backend', + 'tdm-backend.c', + dependencies: common_deps, + install_dir: libds_bindir, + install : true) + + executable('tinyds-tdm', + ['tinyds-tdm.c', 'tinyds-helper.c'], + dependencies: [ + common_deps, + dependency('pixman-1', required: true), + dependency('libdrm', required: true), + dependency('libtbm', required: true), + ], + install_dir: libds_bindir, + install : true) +endif diff --git a/include/meson.build b/include/meson.build index 731f7d3..f273424 100644 --- a/include/meson.build +++ b/include/meson.build @@ -1,3 +1,13 @@ +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') + install_dir: get_option('includedir'), + exclude_files: exclude_files, ) diff --git a/meson.build b/meson.build index 36bfda9..2bf1398 100644 --- a/meson.build +++ b/meson.build @@ -25,6 +25,10 @@ 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('include') subdir('src') @@ -32,10 +36,4 @@ subdir('examples') configure_file(output: 'config.h', install: false, configuration: cdata) -pkgconfig = import('pkgconfig') -pkgconfig.generate(lib_libds, - version: meson.project_version(), - filebase: meson.project_name(), - name: meson.project_name(), - description: 'Wayland compositor library', -) +summary(features, bool_yn: true) diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 0000000..02af9b0 --- /dev/null +++ b/meson_options.txt @@ -0,0 +1 @@ +option('backends', type: 'array', choices: ['auto', 'tdm'], value: ['auto'], description: 'Select built-in backends') diff --git a/src/libds/allocator/allocator.c b/src/libds/allocator.c similarity index 100% rename from src/libds/allocator/allocator.c rename to src/libds/allocator.c diff --git a/src/libds/allocator/meson.build b/src/libds/allocator/meson.build new file mode 100644 index 0000000..361f96e --- /dev/null +++ b/src/libds/allocator/meson.build @@ -0,0 +1,12 @@ +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 c24f074..b1fff87 100644 --- a/src/libds/backend/meson.build +++ b/src/libds/backend/meson.build @@ -1,2 +1,15 @@ +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') -subdir('tdm') diff --git a/src/libds/backend/tdm/meson.build b/src/libds/backend/tdm/meson.build index 9a0b041..82eb165 100644 --- a/src/libds/backend/tdm/meson.build +++ b/src/libds/backend/tdm/meson.build @@ -1,8 +1,32 @@ +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 += [ - dependency('libtdm', required: true), + libtdm, + libtbm ] + +features += { 'tdm-backend': true } diff --git a/src/libds/meson.build b/src/libds/meson.build index e7f2970..ed8c95f 100644 --- a/src/libds/meson.build +++ b/src/libds/meson.build @@ -2,9 +2,7 @@ libds_files = [ 'log.c', 'addon.c', 'buffer.c', - 'allocator/allocator.c', - 'allocator/shm.c', - 'allocator/tbm.c', + 'allocator.c', 'swapchain.c', 'output.c', 'compositor.c', @@ -52,7 +50,6 @@ math = meson.get_compiler('c').find_library('m') wayland_server = dependency('wayland-server', required: true) pixman = dependency('pixman-1', required: true) libdrm = dependency('libdrm', required: true) -libtbm = dependency('libtbm', required: true) libds_deps = [ math, @@ -62,6 +59,7 @@ libds_deps = [ ] subdir('backend') +subdir('allocator') lib_libds = shared_library('ds', libds_files, dependencies: libds_deps, @@ -70,8 +68,23 @@ 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') +pkgconfig.generate(lib_libds, + version: meson.project_version(), + filebase: meson.project_name(), + name: meson.project_name(), + description: 'Wayland compositor library', + variables: ds_vars, ) -- 2.7.4 From e521d2e449f43cacc36297bfdc794538deefdc1f Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Wed, 2 Mar 2022 11:43:09 +0900 Subject: [PATCH 02/16] backend/tdm: Extract buffer code into functions Change-Id: I28a2f6bec27f85f80bcf91f1ce3cad7d4296d940 --- src/libds/backend/tdm/output.c | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/src/libds/backend/tdm/output.c b/src/libds/backend/tdm/output.c index 08b56b5..d3317f3 100644 --- a/src/libds/backend/tdm/output.c +++ b/src/libds/backend/tdm/output.c @@ -142,6 +142,31 @@ get_or_create_tdm_buffer(struct ds_tdm_backend *backend, } static void +tdm_buffer_release(struct ds_tdm_buffer *buffer) +{ + buffer->released = true; + ds_buffer_unlock(buffer->buffer); +} + +static void +tdm_output_update_front_buffer(struct ds_tdm_output *output) +{ + if (output->front_buffer) + tdm_buffer_release(output->front_buffer); + output->front_buffer = output->back_buffer; + output->back_buffer = NULL; +} + +static void +tdm_output_attach_back_buffer(struct ds_tdm_output *output, + struct ds_tdm_buffer *buffer) +{ + if (output->back_buffer) + tdm_buffer_release(output->back_buffer); + 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) { @@ -149,13 +174,7 @@ tdm_output_hwc_commit_handler(tdm_hwc *hwc, unsigned int sequence, output = user_data; - if (output->front_buffer) { - output->front_buffer->released = true; - ds_buffer_unlock(output->front_buffer->buffer); - } - - output->front_buffer = output->back_buffer; - output->back_buffer = NULL; + tdm_output_update_front_buffer(output); wl_signal_emit(&output->base.events.frame, &output->base); } @@ -209,12 +228,7 @@ tdm_output_iface_commit(struct ds_output *ds_output) return false; } - if (output->back_buffer) { - output->back_buffer->released = true; - ds_buffer_unlock(output->back_buffer->buffer); - } - - output->back_buffer = buffer; + tdm_output_attach_back_buffer(output, buffer); ds_dbg("Swap Buffer!!!!!"); } -- 2.7.4 From 7eeb8e9a2c70f7b3d604bf1af1d23bf3cfc097b9 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Wed, 2 Mar 2022 18:09:39 +0900 Subject: [PATCH 03/16] Add tdm backend server and client as an example Change-Id: If5305c3ee0ae11d8e0c9d2aed581e4142a2e4c2a --- clients/meson.build | 45 ++++ clients/simple-tbm.c | 502 +++++++++++++++++++++++++++++++++++++++++++ examples/meson.build | 14 +- examples/pixman-helper.c | 89 ++++++++ examples/pixman-helper.h | 15 ++ examples/tbm-server-helper.c | 222 +++++++++++++++++++ examples/tbm-server-helper.h | 35 +++ examples/tinyds-helper.c | 18 -- examples/tinyds-helper.h | 15 -- examples/tinyds-tdm.c | 173 ++++++--------- meson.build | 1 + packaging/libds.spec | 2 + 12 files changed, 988 insertions(+), 143 deletions(-) create mode 100644 clients/meson.build create mode 100644 clients/simple-tbm.c create mode 100644 examples/pixman-helper.c create mode 100644 examples/pixman-helper.h create mode 100644 examples/tbm-server-helper.c create mode 100644 examples/tbm-server-helper.h delete mode 100644 examples/tinyds-helper.c delete mode 100644 examples/tinyds-helper.h diff --git a/clients/meson.build b/clients/meson.build new file mode 100644 index 0000000..360c425 --- /dev/null +++ b/clients/meson.build @@ -0,0 +1,45 @@ +wayland_tbm_client = dependency('wayland-tbm-client', required: false) +libtbm = dependency('libtbm', required: false) + +if not wayland_tbm_client.found() or not libtbm.found() + subdir_done() +endif + +simple_tbm_files = ['simple-tbm.c'] +simple_tbm_deps = [ + dependency('wayland-client', required: true), + wayland_tbm_client, + libtbm, +] + +protocols = { + 'xdg-shell': wl_protocol_dir / 'stable/xdg-shell/xdg-shell.xml', +} + +protocols_code = {} +protocols_client_header = {} +foreach name, path : protocols + code = custom_target( + name.underscorify() + '_c', + input: path, + output: '@BASENAME@-protocol.c', + command: [wayland_scanner, 'private-code', '@INPUT@', '@OUTPUT@'], + ) + simple_tbm_files += code + + client_header = custom_target( + name.underscorify() + '_client_h', + input: path, + output: '@BASENAME@-client-protocol.h', + command: [wayland_scanner, 'client-header', '@INPUT@', '@OUTPUT@'], + build_by_default: false, + ) + simple_tbm_files += client_header +endforeach + +executable('ds-simple-tbm', + simple_tbm_files, + dependencies: simple_tbm_deps, + install_dir: libds_bindir, + install: true, +) diff --git a/clients/simple-tbm.c b/clients/simple-tbm.c new file mode 100644 index 0000000..f572b60 --- /dev/null +++ b/clients/simple-tbm.c @@ -0,0 +1,502 @@ +/* + * Copyright © 2011 Benjamin Franzke + * Copyright © 2010 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "xdg-shell-client-protocol.h" + +static uint64_t buffer_info_key; +#define BUFFER_INFO_KEY (unsigned long)(&buffer_info_key) + +struct display { + struct wl_display *display; + struct wl_registry *registry; + struct wl_compositor *compositor; + struct xdg_wm_base *wm_base; + struct wl_shm *shm; + struct wayland_tbm_client *wl_tbm; + bool has_xrgb; +}; + +struct window { + struct display *display; + int width, height; + struct wl_surface *surface; + struct xdg_surface *xdg_surface; + struct xdg_toplevel *xdg_toplevel; + struct wl_callback *callback; + tbm_surface_queue_h surface_queue; + bool wait_for_configure; +}; + +struct buffer_info { + struct window *window; + struct wl_buffer *wl_buffer; +}; + +static int running = 1; + +static void +redraw(void *data, struct wl_callback *callback, uint32_t time); + +static void +handle_xdg_surface_configure(void *data, struct xdg_surface *surface, + uint32_t serial) +{ + struct window *window = data; + + xdg_surface_ack_configure(surface, serial); + + if (window->wait_for_configure) { + redraw(window, NULL, 0); + window->wait_for_configure = false; + } +} + +static const struct xdg_surface_listener xdg_surface_listener = { + handle_xdg_surface_configure, +}; + +static void +handle_xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel, + int32_t width, int32_t height, + struct wl_array *state) +{ +} + +static void +handle_xdg_toplevel_close(void *data, struct xdg_toplevel *xdg_toplevel) +{ + running = 0; +} + +static const struct xdg_toplevel_listener xdg_toplevel_listener = { + handle_xdg_toplevel_configure, + handle_xdg_toplevel_close, +}; + +static struct window * +create_window(struct display *display, int width, int height) +{ + struct window *window; + + window = calloc(1, sizeof *window); + if (!window) + return NULL; + + window->callback = NULL; + window->display = display; + window->width = width; + window->height = height; + window->surface = wl_compositor_create_surface(display->compositor); + + if (display->wm_base) { + window->xdg_surface = + xdg_wm_base_get_xdg_surface(display->wm_base, + window->surface); + assert(window->xdg_surface); + xdg_surface_add_listener(window->xdg_surface, + &xdg_surface_listener, window); + + window->xdg_toplevel = + xdg_surface_get_toplevel(window->xdg_surface); + assert(window->xdg_toplevel); + xdg_toplevel_add_listener(window->xdg_toplevel, + &xdg_toplevel_listener, window); + + xdg_toplevel_set_title(window->xdg_toplevel, "simple-tbm"); + wl_surface_commit(window->surface); + window->wait_for_configure = true; + } else { + assert(0); + } + + window->surface_queue = + wayland_tbm_client_create_surface_queue(display->wl_tbm, + window->surface, + 3, + width, + height, + TBM_FORMAT_XRGB8888); + assert(window->surface_queue); + + return window; +} + +static void +destroy_window(struct window *window) +{ + tbm_surface_queue_destroy(window->surface_queue); + + if (window->callback) + wl_callback_destroy(window->callback); + + if (window->xdg_toplevel) + xdg_toplevel_destroy(window->xdg_toplevel); + if (window->xdg_surface) + xdg_surface_destroy(window->xdg_surface); + wl_surface_destroy(window->surface); + free(window); +} + +static void +paint_pixels(void *image, int padding, int width, int height, uint32_t time) +{ + const int halfh = padding + (height - padding * 2) / 2; + const int halfw = padding + (width - padding * 2) / 2; + int ir, or; + uint32_t *pixel = image; + int y; + + /* squared radii thresholds */ + or = (halfw < halfh ? halfw : halfh) - 8; + ir = or - 32; + or *= or; + ir *= ir; + + pixel += padding * width; + for (y = padding; y < height - padding; y++) { + int x; + int y2 = (y - halfh) * (y - halfh); + + pixel += padding; + for (x = padding; x < width - padding; x++) { + uint32_t v; + + /* squared distance from center */ + int r2 = (x - halfw) * (x - halfw) + y2; + + if (r2 < ir) + v = (r2 / 32 + time / 64) * 0x0080401; + else if (r2 < or) + v = (y + time / 32) * 0x0080401; + else + v = (x + time / 16) * 0x0080401; + v &= 0x00ffffff; + + /* cross if compositor uses X from XRGB as alpha */ + if (abs(x - y) > 6 && abs(x + y - height) > 6) + v |= 0xff000000; + + *pixel++ = v; + } + + pixel += padding; + } +} + +static void +buffer_info_free_cb(void *data) +{ + struct buffer_info *buffer_info = data; + + if (!buffer_info) + return; + + wayland_tbm_client_destroy_buffer(buffer_info->window->display->wl_tbm, + buffer_info->wl_buffer); + free(buffer_info); +} + +static void +buffer_handle_release(void *data, struct wl_buffer *wl_buffer) +{ + tbm_surface_h surface = data; + struct buffer_info *buffer_info; + + tbm_surface_internal_get_user_data(surface, BUFFER_INFO_KEY, + (void **)&buffer_info); + if (buffer_info) + tbm_surface_queue_release(buffer_info->window->surface_queue, surface); +} + +static const struct wl_buffer_listener buffer_listener = { + .release = buffer_handle_release, +}; + +static const struct wl_callback_listener frame_listener; + +static void +redraw(void *data, struct wl_callback *callback, uint32_t time) +{ + struct window *window = data; + struct buffer_info *buffer_info = NULL; + tbm_surface_h surface = NULL; + tbm_surface_info_s surface_info; + + if (!tbm_surface_queue_can_dequeue(window->surface_queue, 0)) + return; + + tbm_surface_queue_dequeue(window->surface_queue, &surface); + assert(surface); + + tbm_surface_internal_get_user_data(surface, BUFFER_INFO_KEY, + (void **)&buffer_info); + if (!buffer_info) { + buffer_info = calloc(1, sizeof *buffer_info); + assert(buffer_info); + + tbm_surface_internal_add_user_data(surface, BUFFER_INFO_KEY, buffer_info_free_cb); + tbm_surface_internal_set_user_data(surface, BUFFER_INFO_KEY, buffer_info); + + buffer_info->wl_buffer = + wayland_tbm_client_create_buffer(window->display->wl_tbm, surface); + assert(buffer_info->wl_buffer); + + wl_buffer_add_listener(buffer_info->wl_buffer, &buffer_listener, + surface); + + buffer_info->window = window; + } + + tbm_surface_map(surface, TBM_SURF_OPTION_WRITE, &surface_info); + + paint_pixels(surface_info.planes[0].ptr, 20, + (surface_info.planes[0].stride/4), surface_info.height, time); + + tbm_surface_unmap(surface); + + wl_surface_attach(window->surface, buffer_info->wl_buffer, 0, 0); + wl_surface_damage(window->surface, + 20, 20, window->width - 40, window->height - 40); + + if (callback) + wl_callback_destroy(callback); + + window->callback = wl_surface_frame(window->surface); + wl_callback_add_listener(window->callback, &frame_listener, window); + wl_surface_commit(window->surface); +} + +static const struct wl_callback_listener frame_listener = { + redraw +}; + +static void +shm_format(void *data, struct wl_shm *wl_shm, uint32_t format) +{ + struct display *d = data; + + if (format == WL_SHM_FORMAT_XRGB8888) + d->has_xrgb = true; +} + +struct wl_shm_listener shm_listener = { + shm_format +}; + +static void +xdg_wm_base_ping(void *data, struct xdg_wm_base *shell, uint32_t serial) +{ + xdg_wm_base_pong(shell, serial); +} + +static const struct xdg_wm_base_listener xdg_wm_base_listener = { + xdg_wm_base_ping, +}; + +static void +registry_handle_global(void *data, struct wl_registry *registry, + uint32_t id, const char *interface, uint32_t version) +{ + struct display *d = data; + + if (strcmp(interface, "wl_compositor") == 0) { + d->compositor = + wl_registry_bind(registry, + id, &wl_compositor_interface, 1); + } else if (strcmp(interface, "xdg_wm_base") == 0) { + d->wm_base = wl_registry_bind(registry, + id, &xdg_wm_base_interface, 1); + xdg_wm_base_add_listener(d->wm_base, &xdg_wm_base_listener, d); + } else if (strcmp(interface, "wl_shm") == 0) { + d->shm = wl_registry_bind(registry, + id, &wl_shm_interface, 1); + wl_shm_add_listener(d->shm, &shm_listener, d); + } +} + +static void +registry_handle_global_remove(void *data, struct wl_registry *registry, + uint32_t name) +{ +} + +static const struct wl_registry_listener registry_listener = { + registry_handle_global, + registry_handle_global_remove +}; + +static struct display * +create_display(void) +{ + struct display *display; + + display = calloc(1, sizeof *display); + if (display == NULL) { + fprintf(stderr, "out of memory\n"); + exit(1); + } + display->display = wl_display_connect(NULL); + assert(display->display); + + display->has_xrgb = false; + display->registry = wl_display_get_registry(display->display); + wl_registry_add_listener(display->registry, + ®istry_listener, display); + wl_display_roundtrip(display->display); + if (display->shm == NULL) { + fprintf(stderr, "No wl_shm global\n"); + exit(1); + } + + wl_display_roundtrip(display->display); + + /* + * Why do we need two roundtrips here? + * + * wl_display_get_registry() sends a request to the server, to which + * the server replies by emitting the wl_registry.global events. + * The first wl_display_roundtrip() sends wl_display.sync. The server + * first processes the wl_display.get_registry which includes sending + * the global events, and then processes the sync. Therefore when the + * sync (roundtrip) returns, we are guaranteed to have received and + * processed all the global events. + * + * While we are inside the first wl_display_roundtrip(), incoming + * events are dispatched, which causes registry_handle_global() to + * be called for each global. One of these globals is wl_shm. + * registry_handle_global() sends wl_registry.bind request for the + * wl_shm global. However, wl_registry.bind request is sent after + * the first wl_display.sync, so the reply to the sync comes before + * the initial events of the wl_shm object. + * + * The initial events that get sent as a reply to binding to wl_shm + * include wl_shm.format. These tell us which pixel formats are + * supported, and we need them before we can create buffers. They + * don't change at runtime, so we receive them as part of init. + * + * When the reply to the first sync comes, the server may or may not + * have sent the initial wl_shm events. Therefore we need the second + * wl_display_roundtrip() call here. + * + * The server processes the wl_registry.bind for wl_shm first, and + * the second wl_display.sync next. During our second call to + * wl_display_roundtrip() the initial wl_shm events are received and + * processed. Finally, when the reply to the second wl_display.sync + * arrives, it guarantees we have processed all wl_shm initial events. + * + * This sequence contains two examples on how wl_display_roundtrip() + * can be used to guarantee, that all reply events to a request + * have been received and processed. This is a general Wayland + * technique. + */ + + if (!display->has_xrgb) { + fprintf(stderr, "WL_SHM_FORMAT_XRGB32 not available\n"); + exit(1); + } + + display->wl_tbm = wayland_tbm_client_init(display->display); + if (!display->wl_tbm) { + fprintf(stderr, "failed wayland_tbm_client_init()\n"); + exit(1); + } + + return display; +} + +static void +destroy_display(struct display *display) +{ + if (display->shm) + wl_shm_destroy(display->shm); + + if (display->wm_base) + xdg_wm_base_destroy(display->wm_base); + + if (display->compositor) + wl_compositor_destroy(display->compositor); + + wayland_tbm_client_deinit(display->wl_tbm); + wl_registry_destroy(display->registry); + wl_display_flush(display->display); + wl_display_disconnect(display->display); + free(display); +} + +static void +signal_int(int signum) +{ + running = 0; +} + +int +main(int argc, char **argv) +{ + struct sigaction sigint; + struct display *display; + struct window *window; + int ret = 0; + + display = create_display(); + window = create_window(display, 250, 250); + if (!window) + return 1; + + sigint.sa_handler = signal_int; + sigemptyset(&sigint.sa_mask); + sigint.sa_flags = SA_RESETHAND; + sigaction(SIGINT, &sigint, NULL); + + /* Initialise damage to full surface, so the padding gets painted */ + wl_surface_damage(window->surface, 0, 0, + window->width, window->height); + + if (!window->wait_for_configure) + redraw(window, NULL, 0); + + while (running && ret != -1) + ret = wl_display_dispatch(display->display); + + fprintf(stderr, "simple-shm exiting\n"); + + destroy_window(window); + destroy_display(display); + + return 0; +} diff --git a/examples/meson.build b/examples/meson.build index 66336f5..7a841e4 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -24,16 +24,24 @@ if features.get('tdm-backend') 'tdm-backend.c', dependencies: common_deps, install_dir: libds_bindir, - install : true) + install : true + ) + tinyds_tdm_files = [ + 'tinyds-tdm.c', + 'tbm-server-helper.c', + 'pixman-helper.c', + ] executable('tinyds-tdm', - ['tinyds-tdm.c', 'tinyds-helper.c'], + 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), ], install_dir: libds_bindir, - install : true) + install : true + ) endif diff --git a/examples/pixman-helper.c b/examples/pixman-helper.c new file mode 100644 index 0000000..5d42ec6 --- /dev/null +++ b/examples/pixman-helper.c @@ -0,0 +1,89 @@ +#include "pixman-helper.h" + +#include +#include + +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, + enum ds_buffer_data_ptr_access_flag access_flag) +{ + pixman_image_t *image; + void *data; + uint32_t format; + size_t stride; + int width, height; + + ds_buffer_get_size(buffer, &width, &height); + + if (!ds_buffer_begin_data_ptr_access(buffer, + access_flag, &data, &format, &stride)) + return NULL; + + format = convert_drm_format_to_pixman(format); + image = pixman_image_create_bits(format, width, height, data, stride); + if (!image) { + ds_buffer_end_data_ptr_access(buffer); + return NULL; + } + + pixman_image_set_destroy_function(image, + destroy_pixman_image, ds_buffer_lock(buffer)); + + return image; +} + + +void +pixman_image_fill_color(pixman_image_t *image, uint8_t r, uint8_t g, uint8_t b) +{ + pixman_image_t *color_image; + pixman_color_t color; + + color_rgb888(&color, r, g, b); + color_image = pixman_image_create_solid_fill(&color); + pixman_image_composite32(PIXMAN_OP_SRC, + color_image, + NULL, + image, + 0, 0, 0, 0, 0, 0, + pixman_image_get_width(image), + pixman_image_get_height(image)); + pixman_image_unref(color_image); +} + +static pixman_color_t * +color_rgb888(pixman_color_t *tmp, uint8_t r, uint8_t g, uint8_t b) +{ + tmp->alpha = 65535; + tmp->red = (r << 8) + r; + tmp->green = (g << 8) + g; + tmp->blue = (b << 8) +b; + + return tmp; +} + +static uint32_t +convert_drm_format_to_pixman(uint32_t fmt) +{ + switch (fmt) { + case DRM_FORMAT_XRGB8888: + return PIXMAN_x8r8g8b8; + case DRM_FORMAT_ARGB8888: + return PIXMAN_a8r8g8b8; + default: + assert(0 && "not reached"); + } +} + +static void +destroy_pixman_image(pixman_image_t *image, void *data) +{ + struct ds_buffer *buffer = data; + ds_buffer_end_data_ptr_access(buffer); + ds_buffer_unlock(buffer); +} diff --git a/examples/pixman-helper.h b/examples/pixman-helper.h new file mode 100644 index 0000000..aa039ff --- /dev/null +++ b/examples/pixman-helper.h @@ -0,0 +1,15 @@ +#ifndef EXAMPLES_PIXMAN_HELPER_H +#define EXAMPLES_PIXMAN_HELPER_H + +#include +#include + +pixman_image_t * +pixman_image_from_buffer(struct ds_buffer *buffer, + enum ds_buffer_data_ptr_access_flag access_flag); + +void +pixman_image_fill_color(pixman_image_t *image, + uint8_t r, uint8_t g, uint8_t b); + +#endif diff --git a/examples/tbm-server-helper.c b/examples/tbm-server-helper.c new file mode 100644 index 0000000..bd3a34d --- /dev/null +++ b/examples/tbm-server-helper.c @@ -0,0 +1,222 @@ +#include "tbm-server-helper.h" + +#include +#include +#include +#include +#include +#include + +static const struct ds_buffer_resource_interface tbm_buffer_resource_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) +{ + tbm_bufmgr bufmgr; + + tbm->wl_tbm = wayland_tbm_server_init(display, NULL, -1, 0); + if (!tbm->wl_tbm) { + return false; + } + + bufmgr = wayland_tbm_server_get_bufmgr(tbm->wl_tbm); + if (!bufmgr) { + wayland_tbm_server_deinit(tbm->wl_tbm); + return false; + } + + if (!tbm_bufmgr_bind_native_display(bufmgr, (void *)display)) { + wayland_tbm_server_deinit(tbm->wl_tbm); + return false; + } + + 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; +} + +static void +tbm_server_handle_display_destroy(struct wl_listener *listener, void *data) +{ + struct tbm_server *tbm; + + tbm = wl_container_of(listener, tbm, display_destroy); + wayland_tbm_server_deinit(tbm->wl_tbm); +} + +static bool +tbm_buffer_resource_iface_is_instance(struct wl_resource *resource) +{ + return !!wayland_tbm_server_get_surface(NULL, resource); +} + +static void +tbm_client_buffer_handle_resource_destroy(struct wl_listener *listener, + void *data) +{ + struct tbm_client_buffer *buffer; + + buffer = wl_container_of(listener, buffer, resource_destroy); + + buffer->resource = NULL; + buffer->surface = NULL; + wl_list_remove(&buffer->resource_destroy.link); + wl_list_init(&buffer->resource_destroy.link); + + 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) +{ + struct tbm_client_buffer *buffer; + + buffer = tbm_client_buffer_get_or_create(resource); + assert(buffer); + + 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, +}; + +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) +{ + struct tbm_client_buffer *buffer; + + buffer = tbm_client_buffer_from_buffer(ds_buffer); + + ds_inf("Destroy TBM client buffer(%p)", buffer); + + wl_list_remove(&buffer->resource_destroy.link); + wl_list_remove(&buffer->buffer_release.link); + free(buffer); +} + +static bool +tbm_client_buffer_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; + tbm_surface_info_s info; + tbm_bo_access_option op = TBM_OPTION_NONE; + int err; + + buffer = tbm_client_buffer_from_buffer(ds_buffer); + + if (flags & DS_BUFFER_DATA_PTR_ACCESS_READ) + op |= TBM_OPTION_READ; + + if (flags & DS_BUFFER_DATA_PTR_ACCESS_WRITE) + op |= TBM_OPTION_WRITE; + + err = tbm_surface_map(buffer->surface, op, &info); + if (err != TBM_SURFACE_ERROR_NONE) { + ds_err("Failed tbm_surface_map()"); + return false; + } + + *format = DRM_FORMAT_XRGB8888; // FIXME + *stride = info.planes[0].stride; + *data = info.planes[0].ptr; + + return true; +} + +static void +tbm_client_buffer_end_data_ptr_access(struct ds_buffer *ds_buffer) +{ + struct tbm_client_buffer *buffer; + + buffer = tbm_client_buffer_from_buffer(ds_buffer); + + tbm_surface_unmap(buffer->surface); +} + +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, +}; + +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 * +tbm_client_buffer_create(struct wl_resource *resource) +{ + struct tbm_client_buffer *buffer; + tbm_surface_h surface; + int32_t width, height; + + surface = wayland_tbm_server_get_surface(NULL, resource); + assert(surface); + + width = tbm_surface_get_width(surface); + height = tbm_surface_get_height(surface); + + buffer = calloc(1, sizeof *buffer); + assert(buffer); + + ds_buffer_init(&buffer->base, &tbm_client_buffer_iface, width, height); + + buffer->resource = resource; + buffer->surface = surface; + buffer->format = tbm_surface_get_format(surface); + + buffer->buffer_release.notify = tbm_client_buffer_handle_release; + ds_buffer_add_release_listener(&buffer->base, &buffer->buffer_release); + + buffer->resource_destroy.notify = + tbm_client_buffer_handle_resource_destroy; + wl_resource_add_destroy_listener(resource, &buffer->resource_destroy); + + ds_inf("TBM client buffer(%p) created", buffer); + + return buffer; +} diff --git a/examples/tbm-server-helper.h b/examples/tbm-server-helper.h new file mode 100644 index 0000000..a82ad5b --- /dev/null +++ b/examples/tbm-server-helper.h @@ -0,0 +1,35 @@ +#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); + +#endif diff --git a/examples/tinyds-helper.c b/examples/tinyds-helper.c deleted file mode 100644 index ef077b3..0000000 --- a/examples/tinyds-helper.c +++ /dev/null @@ -1,18 +0,0 @@ -#include "tinyds-helper.h" - -#include -#include - -bool -tinyds_renderer_init_display(struct tinyds_renderer *renderer, - struct wl_display *display) -{ - if (wl_display_init_shm(display)) { - ds_err("Could not initialize shm"); - return false; - } - - renderer->dummy = 1; - - return true; -} diff --git a/examples/tinyds-helper.h b/examples/tinyds-helper.h deleted file mode 100644 index 44415d6..0000000 --- a/examples/tinyds-helper.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef TINYDS_HELPER_H -#define TINYDS_HELPER_H - -#include -#include - -struct tinyds_renderer { - int dummy; -}; - -bool -tinyds_renderer_init_display(struct tinyds_renderer *renderer, - struct wl_display *display); - -#endif diff --git a/examples/tinyds-tdm.c b/examples/tinyds-tdm.c index 23ff48e..4207fb1 100644 --- a/examples/tinyds-tdm.c +++ b/examples/tinyds-tdm.c @@ -1,4 +1,5 @@ -#include "tinyds-helper.h" +#include "tbm-server-helper.h" +#include "pixman-helper.h" #include #include @@ -43,6 +44,8 @@ struct tinyds_output struct tinyds_server { + struct tbm_server tbm_server; + struct wl_display *display; struct ds_backend *backend; @@ -50,7 +53,7 @@ struct tinyds_server struct ds_xdg_shell *xdg_shell; struct tinyds_output *output; - struct tinyds_renderer renderer; + struct wl_event_source *stdin_source; struct wl_list views; @@ -74,12 +77,12 @@ struct tinyds_view bool mapped; }; -struct tinyds_server _tinyds; +struct tinyds_server tinyds; static bool init_server(struct tinyds_server *server, struct wl_display *display); +static int server_dispatch_stdin(int fd, uint32_t mask, void *data); 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(struct tinyds_server *server); static void draw_server_with_damage(struct tinyds_server *server); static void draw_output(struct tinyds_output *output); static void draw_view(struct tinyds_view *view, pixman_image_t *dst_image); @@ -87,18 +90,22 @@ static void draw_view(struct tinyds_view *view, pixman_image_t *dst_image); int main(void) { - struct tinyds_server *server = &_tinyds; + struct tinyds_server *server = &tinyds; struct wl_display *display; + struct wl_event_loop *loop; const char *socket; + bool res; - ds_log_init(DS_DBG, NULL); + ds_log_init(DS_INF, NULL); display = wl_display_create(); assert(display); - assert(init_server(server, display) == true); + res = init_server(server, display); + assert(res); - assert(tinyds_renderer_init_display(&server->renderer, display)); + res = tbm_server_init_display(&server->tbm_server, display); + assert(res); socket = wl_display_add_socket_auto(display); assert(socket); @@ -109,6 +116,13 @@ main(void) ds_inf("Running Wayland compositor on WAYLAND_DISPLAY=%s", socket); + loop = wl_display_get_event_loop(display); + server->stdin_source = wl_event_loop_add_fd(loop, STDIN_FILENO, + WL_EVENT_READABLE, server_dispatch_stdin, server); + + wl_display_run(display); + + wl_display_destroy_clients(display); wl_display_destroy(display); return 0; @@ -175,6 +189,8 @@ server_new_xdg_surface(struct wl_listener *listener, void *data) ds_inf("New xdg_surface(%p)", (void *)xdg_surface); view = calloc(1, sizeof *view); + assert(view); + view->server = server; view->xdg_surface = xdg_surface; @@ -196,6 +212,9 @@ server_new_xdg_surface(struct wl_listener *listener, void *data) &view->surface_commit); wl_list_insert(server->views.prev, &view->link); + + view->x = rand() % 1000; + view->y = rand() % 500; } static void @@ -217,8 +236,24 @@ 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, + OUTPUT_WIDTH, OUTPUT_HEIGHT, DRM_FORMAT_XRGB8888); // FIXME output mode + if (!output->swapchain) { + ds_allocator_destroy(output->allocator); + free(output); + return; + } + output->server = server; output->ds_output = ds_output; + output->drawable = true; + output->damaged = true; output->output_destroy.notify = output_handle_destroy; ds_output_add_destroy_listener(ds_output, @@ -229,6 +264,8 @@ backend_handle_new_output(struct wl_listener *listener, void *data) &output->output_frame); server->output = output; + + draw_output(output); } static bool @@ -299,12 +336,8 @@ output_handle_frame(struct wl_listener *listener, void *data TINYDS_UNUSED) struct tinyds_output *output = wl_container_of(listener, output, output_frame); -} - -static void -draw_server(struct tinyds_server *server) -{ - draw_output(server->output); + output->drawable = true; + draw_output(output); } static void @@ -314,12 +347,6 @@ draw_server_with_damage(struct tinyds_server *server) draw_output(server->output); } -static void image_fill_color(pixman_image_t *image, - uint8_t r, uint8_t g, uint8_t b); -static pixman_image_t *image_from_buffer(struct ds_buffer *buffer, - enum ds_buffer_data_ptr_access_flag access_flag); -static void view_send_frame_done(struct tinyds_view *view); - static void draw_output(struct tinyds_output *output) { @@ -334,14 +361,14 @@ draw_output(struct tinyds_output *output) if (!output_buffer) return; - output_image = image_from_buffer(output_buffer, + output_image = pixman_image_from_buffer(output_buffer, DS_BUFFER_DATA_PTR_ACCESS_WRITE); if (!output_image) { ds_buffer_unlock(output_buffer); return; } - image_fill_color(output_image, 80, 80, 80); + pixman_image_fill_color(output_image, 80, 80, 80); wl_list_for_each(view, &output->server->views, link) { if (!view->mapped) @@ -362,6 +389,15 @@ draw_output(struct tinyds_output *output) } 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 void draw_view(struct tinyds_view *view, pixman_image_t *dst_image) { struct ds_buffer *buffer; @@ -372,13 +408,14 @@ draw_view(struct tinyds_view *view, pixman_image_t *dst_image) if (!buffer) return; - src_image = image_from_buffer(buffer, + src_image = pixman_image_from_buffer(buffer, DS_BUFFER_DATA_PTR_ACCESS_READ); pixman_image_composite32(PIXMAN_OP_OVER, src_image, NULL, dst_image, - 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + view->x, view->y, pixman_image_get_width(src_image), pixman_image_get_height(src_image)); pixman_image_unref(src_image); @@ -386,90 +423,12 @@ draw_view(struct tinyds_view *view, pixman_image_t *dst_image) view_send_frame_done(view); } -static pixman_color_t * -color_rgb888(pixman_color_t *tmp, uint8_t r, uint8_t g, uint8_t b) +static int +server_dispatch_stdin(int fd, uint32_t mask, void *data) { - tmp->alpha = 65535; - tmp->red = (r << 8) + r; - tmp->green = (g << 8) + g; - tmp->blue = (b << 8) +b; + struct tinyds_server *server = data; - return tmp; -} + wl_display_terminate(server->display); -static void -image_fill_color(pixman_image_t *image, uint8_t r, uint8_t g, uint8_t b) -{ - pixman_image_t *color_image; - pixman_color_t color; - - color_rgb888(&color, r, g, b); - color_image = pixman_image_create_solid_fill(&color); - pixman_image_composite32(PIXMAN_OP_SRC, - color_image, - NULL, - image, - 0, 0, 0, 0, 0, 0, - pixman_image_get_width(image), - pixman_image_get_height(image)); - pixman_image_unref(color_image); -} - -static void -destroy_pixman_image(pixman_image_t *image TINYDS_UNUSED, void *data) -{ - struct ds_buffer *buffer = data; - ds_buffer_end_data_ptr_access(buffer); - ds_buffer_unlock(buffer); -} - -static uint32_t -convert_drm_format_to_pixman(uint32_t fmt) -{ - switch (fmt) { - case DRM_FORMAT_XRGB8888: - return PIXMAN_x8r8g8b8; - case DRM_FORMAT_ARGB8888: - return PIXMAN_a8r8g8b8; - default: - assert(0 && "not reached"); - } -} - -static pixman_image_t * -image_from_buffer(struct ds_buffer *buffer, - enum ds_buffer_data_ptr_access_flag access_flag) -{ - pixman_image_t *image; - void *data; - uint32_t format; - size_t stride; - int width, height; - - ds_buffer_get_size(buffer, &width, &height); - - if (!ds_buffer_begin_data_ptr_access(buffer, - access_flag, &data, &format, &stride)) - return NULL; - - format = convert_drm_format_to_pixman(format); - image = pixman_image_create_bits(format, width, height, data, stride); - if (!image) { - ds_buffer_end_data_ptr_access(buffer); - return NULL; - } - - pixman_image_set_destroy_function(image, - destroy_pixman_image, ds_buffer_lock(buffer)); - - return image; -} - -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); + return 1; } diff --git a/meson.build b/meson.build index 2bf1398..445fd6a 100644 --- a/meson.build +++ b/meson.build @@ -33,6 +33,7 @@ features = { subdir('include') subdir('src') subdir('examples') +subdir('clients') configure_file(output: 'config.h', install: false, configuration: cdata) diff --git a/packaging/libds.spec b/packaging/libds.spec index 69d58f6..3b479e2 100644 --- a/packaging/libds.spec +++ b/packaging/libds.spec @@ -16,6 +16,8 @@ BuildRequires: pkgconfig(libdrm) BuildRequires: pkgconfig(libtdm) BuildRequires: pkgconfig(libtbm) +BuildRequires: pkgconfig(wayland-tbm-server) +BuildRequires: pkgconfig(wayland-tbm-client) %description Wayland Compositor Library -- 2.7.4 From efacbd2b7543333547793715b0e411bd5dc8130f Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Wed, 2 Mar 2022 18:14:12 +0900 Subject: [PATCH 04/16] examples: Use pixman helper Change-Id: I22a63f7af7c9b054d2be52f1e6dbbe92291ee96d --- examples/meson.build | 20 +++++++----- examples/tinyds.c | 91 +++------------------------------------------------- 2 files changed, 17 insertions(+), 94 deletions(-) diff --git a/examples/meson.build b/examples/meson.build index 7a841e4..193b4a5 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -10,14 +10,18 @@ executable('wl-backend', install : true) executable('tinyds', - 'tinyds.c', - dependencies: [ - common_deps, - dependency('pixman-1', required: true), - dependency('libdrm', required: true), - ], - install_dir: libds_bindir, - install : true) + [ + 'tinyds.c', + 'pixman-helper.c' + ], + dependencies: [ + common_deps, + dependency('pixman-1', required: true), + dependency('libdrm', required: true), + ], + install_dir: libds_bindir, + install : true +) if features.get('tdm-backend') executable('tdm-backend', diff --git a/examples/tinyds.c b/examples/tinyds.c index 3925014..a4c1042 100644 --- a/examples/tinyds.c +++ b/examples/tinyds.c @@ -1,3 +1,5 @@ +#include "pixman-helper.h" + #include #include #include @@ -361,10 +363,6 @@ draw_server_with_damage(struct tinyds_server *server) } } -static void image_fill_color(pixman_image_t *image, - uint8_t r, uint8_t g, uint8_t b); -static pixman_image_t *image_from_buffer(struct ds_buffer *buffer, - enum ds_buffer_data_ptr_access_flag access_flag); static void view_send_frame_done(struct tinyds_view *view); static void @@ -381,14 +379,14 @@ draw_output(struct tinyds_output *output) if (!output_buffer) return; - output_image = image_from_buffer(output_buffer, + output_image = pixman_image_from_buffer(output_buffer, DS_BUFFER_DATA_PTR_ACCESS_WRITE); if (!output_image) { ds_buffer_unlock(output_buffer); return; } - image_fill_color(output_image, 80, 80, 80); + pixman_image_fill_color(output_image, 80, 80, 80); wl_list_for_each(view, &output->server->views, link) { if (!view->mapped) @@ -419,7 +417,7 @@ draw_view(struct tinyds_view *view, pixman_image_t *dst_image) if (!buffer) return; - src_image = image_from_buffer(buffer, + src_image = pixman_image_from_buffer(buffer, DS_BUFFER_DATA_PTR_ACCESS_READ); pixman_image_composite32(PIXMAN_OP_OVER, src_image, @@ -433,85 +431,6 @@ draw_view(struct tinyds_view *view, pixman_image_t *dst_image) view_send_frame_done(view); } -static pixman_color_t * -color_rgb888(pixman_color_t *tmp, uint8_t r, uint8_t g, uint8_t b) -{ - tmp->alpha = 65535; - tmp->red = (r << 8) + r; - tmp->green = (g << 8) + g; - tmp->blue = (b << 8) +b; - - return tmp; -} - -static void -image_fill_color(pixman_image_t *image, uint8_t r, uint8_t g, uint8_t b) -{ - pixman_image_t *color_image; - pixman_color_t color; - - color_rgb888(&color, r, g, b); - color_image = pixman_image_create_solid_fill(&color); - pixman_image_composite32(PIXMAN_OP_SRC, - color_image, - NULL, - image, - 0, 0, 0, 0, 0, 0, - pixman_image_get_width(image), - pixman_image_get_height(image)); - pixman_image_unref(color_image); -} - -static void -destroy_pixman_image(pixman_image_t *image TINYDS_UNUSED, void *data) -{ - struct ds_buffer *buffer = data; - ds_buffer_end_data_ptr_access(buffer); - ds_buffer_unlock(buffer); -} - -static uint32_t -convert_drm_format_to_pixman(uint32_t fmt) -{ - switch (fmt) { - case DRM_FORMAT_XRGB8888: - return PIXMAN_x8r8g8b8; - case DRM_FORMAT_ARGB8888: - return PIXMAN_a8r8g8b8; - default: - assert(0 && "not reached"); - } -} - -static pixman_image_t * -image_from_buffer(struct ds_buffer *buffer, - enum ds_buffer_data_ptr_access_flag access_flag) -{ - pixman_image_t *image; - void *data; - uint32_t format; - size_t stride; - int width, height; - - ds_buffer_get_size(buffer, &width, &height); - - if (!ds_buffer_begin_data_ptr_access(buffer, - access_flag, &data, &format, &stride)) - return NULL; - - format = convert_drm_format_to_pixman(format); - image = pixman_image_create_bits(format, width, height, data, stride); - if (!image) { - ds_buffer_end_data_ptr_access(buffer); - return NULL; - } - - pixman_image_set_destroy_function(image, - destroy_pixman_image, ds_buffer_lock(buffer)); - - return image; -} - static void view_send_frame_done(struct tinyds_view *view) { -- 2.7.4 From 4ab31108b1d64790047369ba2e58050d1d6fa1ac Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Thu, 3 Mar 2022 12:11:03 +0900 Subject: [PATCH 05/16] Move all source code to src directory Change-Id: I55fd4d95d633a2a6d557d7409bbd6aba6b4b8d03 --- meson.build | 2 -- {clients => src/clients}/meson.build | 0 {clients => src/clients}/simple-tbm.c | 0 {examples => src/examples}/meson.build | 0 {examples => src/examples}/pixman-helper.c | 0 {examples => src/examples}/pixman-helper.h | 0 {examples => src/examples}/tbm-server-helper.c | 0 {examples => src/examples}/tbm-server-helper.h | 0 {examples => src/examples}/tdm-backend.c | 0 {examples => src/examples}/tinyds-tdm.c | 0 {examples => src/examples}/tinyds.c | 0 {examples => src/examples}/wl-backend.c | 0 src/meson.build | 2 ++ 13 files changed, 2 insertions(+), 2 deletions(-) rename {clients => src/clients}/meson.build (100%) rename {clients => src/clients}/simple-tbm.c (100%) rename {examples => src/examples}/meson.build (100%) rename {examples => src/examples}/pixman-helper.c (100%) rename {examples => src/examples}/pixman-helper.h (100%) rename {examples => src/examples}/tbm-server-helper.c (100%) rename {examples => src/examples}/tbm-server-helper.h (100%) rename {examples => src/examples}/tdm-backend.c (100%) rename {examples => src/examples}/tinyds-tdm.c (100%) rename {examples => src/examples}/tinyds.c (100%) rename {examples => src/examples}/wl-backend.c (100%) diff --git a/meson.build b/meson.build index 445fd6a..0a91447 100644 --- a/meson.build +++ b/meson.build @@ -32,8 +32,6 @@ features = { subdir('include') subdir('src') -subdir('examples') -subdir('clients') configure_file(output: 'config.h', install: false, configuration: cdata) diff --git a/clients/meson.build b/src/clients/meson.build similarity index 100% rename from clients/meson.build rename to src/clients/meson.build diff --git a/clients/simple-tbm.c b/src/clients/simple-tbm.c similarity index 100% rename from clients/simple-tbm.c rename to src/clients/simple-tbm.c diff --git a/examples/meson.build b/src/examples/meson.build similarity index 100% rename from examples/meson.build rename to src/examples/meson.build diff --git a/examples/pixman-helper.c b/src/examples/pixman-helper.c similarity index 100% rename from examples/pixman-helper.c rename to src/examples/pixman-helper.c diff --git a/examples/pixman-helper.h b/src/examples/pixman-helper.h similarity index 100% rename from examples/pixman-helper.h rename to src/examples/pixman-helper.h diff --git a/examples/tbm-server-helper.c b/src/examples/tbm-server-helper.c similarity index 100% rename from examples/tbm-server-helper.c rename to src/examples/tbm-server-helper.c diff --git a/examples/tbm-server-helper.h b/src/examples/tbm-server-helper.h similarity index 100% rename from examples/tbm-server-helper.h rename to src/examples/tbm-server-helper.h diff --git a/examples/tdm-backend.c b/src/examples/tdm-backend.c similarity index 100% rename from examples/tdm-backend.c rename to src/examples/tdm-backend.c diff --git a/examples/tinyds-tdm.c b/src/examples/tinyds-tdm.c similarity index 100% rename from examples/tinyds-tdm.c rename to src/examples/tinyds-tdm.c diff --git a/examples/tinyds.c b/src/examples/tinyds.c similarity index 100% rename from examples/tinyds.c rename to src/examples/tinyds.c diff --git a/examples/wl-backend.c b/src/examples/wl-backend.c similarity index 100% rename from examples/wl-backend.c rename to src/examples/wl-backend.c diff --git a/src/meson.build b/src/meson.build index 2a6ba37..774c7eb 100644 --- a/src/meson.build +++ b/src/meson.build @@ -12,3 +12,5 @@ wayland_scanner = find_program( subdir('libds') subdir('tests') +subdir('examples') +subdir('clients') -- 2.7.4 From 00ed279fa8ad331e8628c14909a3cb324c0602d1 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Mon, 7 Mar 2022 08:09:00 +0900 Subject: [PATCH 06/16] change the version into 0.1.2 Change-Id: I747595f287cf73a548e03e569c6a18f413837d1b --- meson.build | 2 +- packaging/libds.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/meson.build b/meson.build index 0a91447..db1f43c 100644 --- a/meson.build +++ b/meson.build @@ -1,6 +1,6 @@ project('libds', 'c', license: 'MIT', - version: '0.1.0', + version: '0.1.2', default_options: [ 'warning_level=1', 'c_std=gnu99', diff --git a/packaging/libds.spec b/packaging/libds.spec index 3b479e2..bd38de7 100644 --- a/packaging/libds.spec +++ b/packaging/libds.spec @@ -1,5 +1,5 @@ Name: libds -Version: 0.0.1 +Version: 0.1.2 Release: 0 Summary: Wayland Compositor Library License: MIT -- 2.7.4 From 704347f05007f8b4f204b1bebcc511f949f6c325 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Mon, 7 Mar 2022 08:10:09 +0900 Subject: [PATCH 07/16] Put the extern "C" Without this extern "C", C++ program which uses libds does not recognize the symbols in libds header files. Change-Id: I2b9904c6dd9f50eab4c15f66ce3b6d9328b213b2 --- include/libds/allocator.h | 8 ++++++++ include/libds/allocator/shm.h | 8 ++++++++ include/libds/allocator/tbm.h | 8 ++++++++ include/libds/backend/tdm.h | 8 ++++++++ include/libds/backend/wayland.h | 8 ++++++++ include/libds/output.h | 8 ++++++++ include/libds/swapchain.h | 8 ++++++++ include/libds/xdg_shell.h | 8 ++++++++ 8 files changed, 64 insertions(+) diff --git a/include/libds/allocator.h b/include/libds/allocator.h index d4a6a80..7f26a96 100644 --- a/include/libds/allocator.h +++ b/include/libds/allocator.h @@ -3,6 +3,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + struct ds_allocator; void @@ -16,4 +20,8 @@ void ds_allocator_add_destroy_listener(struct ds_allocator *alloc, struct wl_listener *listener); +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/libds/allocator/shm.h b/include/libds/allocator/shm.h index 1a02338..c151183 100644 --- a/include/libds/allocator/shm.h +++ b/include/libds/allocator/shm.h @@ -3,7 +3,15 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + struct ds_allocator * ds_shm_allocator_create(void); +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/libds/allocator/tbm.h b/include/libds/allocator/tbm.h index 1457e3f..c02aee3 100644 --- a/include/libds/allocator/tbm.h +++ b/include/libds/allocator/tbm.h @@ -3,10 +3,18 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + struct ds_allocator * ds_tbm_allocator_create(void); WL_EXPORT void * ds_tbm_buffer_get_surface(struct ds_buffer *ds_buffer); +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/libds/backend/tdm.h b/include/libds/backend/tdm.h index ec5f9cc..e697413 100644 --- a/include/libds/backend/tdm.h +++ b/include/libds/backend/tdm.h @@ -3,7 +3,15 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + struct ds_backend * ds_tdm_backend_create(struct wl_display *display); +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/libds/backend/wayland.h b/include/libds/backend/wayland.h index e7f233a..2be8d76 100644 --- a/include/libds/backend/wayland.h +++ b/include/libds/backend/wayland.h @@ -4,10 +4,18 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + struct ds_backend * ds_wl_backend_create(struct wl_display *display, const char *server_name); struct ds_output * ds_wl_backend_create_output(struct ds_backend *backend); +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/libds/output.h b/include/libds/output.h index d2454fc..d56690e 100644 --- a/include/libds/output.h +++ b/include/libds/output.h @@ -4,6 +4,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + struct ds_output; struct ds_output_mode { @@ -41,4 +45,8 @@ void ds_output_add_commit_listener(struct ds_output *output, struct wl_listener *listener); +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/libds/swapchain.h b/include/libds/swapchain.h index d78d428..61d8a68 100644 --- a/include/libds/swapchain.h +++ b/include/libds/swapchain.h @@ -3,6 +3,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + struct ds_swapchain; struct ds_swapchain * @@ -19,4 +23,8 @@ void ds_swapchain_set_buffer_submitted(struct ds_swapchain *swapchain, struct ds_buffer *buffer); +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/libds/xdg_shell.h b/include/libds/xdg_shell.h index e3b386f..624c327 100644 --- a/include/libds/xdg_shell.h +++ b/include/libds/xdg_shell.h @@ -6,6 +6,10 @@ #include "surface.h" +#ifdef __cplusplus +extern "C" { +#endif + struct ds_xdg_shell; struct ds_xdg_surface; @@ -47,4 +51,8 @@ uint32_t ds_xdg_toplevel_set_activated(struct ds_xdg_surface *surface, bool activated); +#ifdef __cplusplus +} +#endif + #endif -- 2.7.4 From 495555a7d8ded2eed157c5a71afaa4b239e1ff43 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Mon, 7 Mar 2022 08:28:59 +0900 Subject: [PATCH 08/16] add CODEOWNERS which allow the members to be addded as reviewers when the PR is uploaded. Change-Id: I2baae3daff64061cf4436b91b22c64f42ced740a --- CODEOWNERS | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 CODEOWNERS diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000..2c7fc6d --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,9 @@ +# This is a comment. +# Each line is a file pattern followed by one or more owners. + +# These owners will be the default owners for everything in +# 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 + -- 2.7.4 From ca59561daf56a995f7a1a39cb353868f41765ecc Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Thu, 3 Mar 2022 18:01:14 +0900 Subject: [PATCH 09/16] Annotate a refresh variable Change-Id: I6019b86ea994d8fc4073eaf0cdba318489f844a5 --- include/libds/output.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/libds/output.h b/include/libds/output.h index d56690e..35fee14 100644 --- a/include/libds/output.h +++ b/include/libds/output.h @@ -12,7 +12,7 @@ struct ds_output; struct ds_output_mode { int32_t width, height; - int32_t refresh; + int32_t refresh; // mHz bool preferred; struct wl_list link; }; -- 2.7.4 From 976fd811f38ab83a2cc061c216d36881a10ab362 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Thu, 3 Mar 2022 18:02:49 +0900 Subject: [PATCH 10/16] backend/tdm: Update output mode Change-Id: I1c23428392249f74376dc40aae5da89011165b17 --- src/libds/backend/tdm/output.c | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/src/libds/backend/tdm/output.c b/src/libds/backend/tdm/output.c index d3317f3..06edbf6 100644 --- a/src/libds/backend/tdm/output.c +++ b/src/libds/backend/tdm/output.c @@ -10,6 +10,7 @@ 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); struct ds_tdm_output * create_tdm_output(struct ds_tdm_backend *tdm, tdm_output *tdm_output) @@ -188,6 +189,13 @@ tdm_output_iface_commit(struct ds_output *ds_output) output = tdm_output_from_output(ds_output); + if (ds_output->pending.committed & DS_OUTPUT_STATE_MODE) { + if (!tdm_output_update_mode(output)) { + ds_err("Could not update TDM mode"); + return false; + } + } + ds_buffer = ds_output->pending.buffer; buffer = get_or_create_tdm_buffer(output->backend, ds_buffer); if (!buffer) @@ -221,7 +229,8 @@ tdm_output_iface_commit(struct ds_output *ds_output) return false; } - err = tdm_hwc_commit(output->tdm.hwc, 0, tdm_output_hwc_commit_handler, output); + 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); @@ -295,7 +304,7 @@ tdm_output_init_modes(struct ds_tdm_output *output) if (tdm_mode->type & TDM_OUTPUT_MODE_TYPE_PREFERRED) mode->base.preferred = true; - ds_inf(" %dx%d@%d %s", mode->base.width, mode->base.height, + ds_dbg(" %dx%d@%d %s", mode->base.width, mode->base.height, mode->base.refresh, mode->base.preferred ? "(preferred)" : ""); @@ -303,14 +312,6 @@ tdm_output_init_modes(struct ds_tdm_output *output) wl_list_insert(&output->base.modes, &mode->base.link); else wl_list_insert(output->base.modes.prev, &mode->base.link); - - // FIXME - if (mode->base.preferred) { - err = tdm_output_set_mode(output->tdm.output, tdm_mode); - if (err != TDM_ERROR_NONE) { - ds_err("Could not set mode"); - } - } } return true; @@ -327,3 +328,21 @@ tdm_output_init_hwc(struct ds_tdm_output *output) return; } } + +static bool +tdm_output_update_mode(struct ds_tdm_output *output) +{ + const struct ds_tdm_output_mode *mode; + tdm_error err; + + mode = (struct ds_tdm_output_mode *)output->base.pending.mode; + + ds_inf("TDM output(%p) set mode %dx%d %d mHz", output, + mode->base.width, mode->base.height, mode->base.refresh); + + err = tdm_output_set_mode(output->tdm.output, mode->tdm_mode); + if (err != TDM_ERROR_NONE) + return false; + + return true; +} -- 2.7.4 From 7f7bb930fcef308974d56fb0fd0d2e37e9347ceb Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Thu, 3 Mar 2022 18:03:25 +0900 Subject: [PATCH 11/16] examples: Use output mode instead of arbitrary size Change-Id: I46b576bccbd469ed386dc4d284a7a71311e557af --- 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 63c4efe7fab181adf306abb742a40e6d54bb7a6c Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Thu, 3 Mar 2022 19:01:28 +0900 Subject: [PATCH 12/16] backend/tdm: Get buffer only if it's necessary Change-Id: I740870ecdf85e855fc583141bccc3a73dd8e4fec --- 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 0fbf71a8ff23b0fe10792953950d7dd0743d7164 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Thu, 3 Mar 2022 19:03:50 +0900 Subject: [PATCH 13/16] output: Rename function more explicitly Change-Id: I97122db26edd0163f5a70dc5eafaace4df1d4127 --- 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 fd092a63621eb215ad68aff239df556a7be8a677 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Fri, 4 Mar 2022 10:44:57 +0900 Subject: [PATCH 14/16] backend/tdm: Split commit function into small functions No functional changes. It improves readability. Change-Id: Ib762d10a2ad085da18b2c21e00cbb66f2193d345 --- 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 5b464e44bdc24e2caf8408279f9131ecaa29d375 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Fri, 4 Mar 2022 10:49:50 +0900 Subject: [PATCH 15/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: I917a027f0c94c67c18d3b7823bc216eed0080b60 --- 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 d6c0be1bfe70ede248dbbfe1f752f43776d97560 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Fri, 4 Mar 2022 14:25:20 +0900 Subject: [PATCH 16/16] Fix formatting Change-Id: I01c89e5adaa5180a116cc61fedce055bb90290bd --- 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