diff --git a/.builds/alpine.yml b/.builds/alpine.yml index f8d75d8b1..affd85411 100644 --- a/.builds/alpine.yml +++ b/.builds/alpine.yml @@ -35,9 +35,6 @@ tasks: cd wlroots ninja -C build sudo ninja -C build install - - test: | - cd wlroots - meson test -C build --verbose - build-features-disabled: | cd wlroots meson setup build --reconfigure -Dauto_features=disabled diff --git a/.builds/archlinux.yml b/.builds/archlinux.yml index 84e04eda7..fae04ab31 100644 --- a/.builds/archlinux.yml +++ b/.builds/archlinux.yml @@ -37,10 +37,6 @@ tasks: - clang: | cd wlroots/build-clang ninja - - test: | - cd wlroots/build-gcc - meson test --verbose - meson test --benchmark --verbose - smoke-test: | cd wlroots/build-gcc/tinywl sudo modprobe vkms diff --git a/.builds/freebsd.yml b/.builds/freebsd.yml index 3bfe37489..a99e9c911 100644 --- a/.builds/freebsd.yml +++ b/.builds/freebsd.yml @@ -32,9 +32,6 @@ tasks: meson setup build --fatal-meson-warnings -Dauto_features=enabled -Dallocators=gbm ninja -C build sudo ninja -C build install - - test: | - cd wlroots - meson test -C build --verbose - tinywl: | cd wlroots/tinywl make diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3b02ef16f..e02463a9c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,4 +1,4 @@ -include: https://gitlab.freedesktop.org/emersion/dalligi/-/raw/master/templates/multi.yml +include: https://git.sr.ht/~emersion/dalligi/blob/master/templates/multi.yml alpine: extends: .dalligi pages: true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d9c49f7c2..aea7d6960 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -22,7 +22,7 @@ don't, however, allow me to make a suggestion: feature branches pulled from upstream. Try this: 1. Fork wlroots -2. `git clone git@ssh.gitlab.freedesktop.org:/wlroots.git && cd wlroots` +2. `git clone git@gitlab.freedesktop.org:/wlroots.git && cd wlroots` 3. `git remote add upstream https://gitlab.freedesktop.org/wlroots/wlroots.git` You only need to do this once. You're never going to use your fork's master diff --git a/backend/drm/atomic.c b/backend/drm/atomic.c index daa8ba9bf..41773d4f5 100644 --- a/backend/drm/atomic.c +++ b/backend/drm/atomic.c @@ -1,4 +1,3 @@ -#include #include #include #include @@ -424,6 +423,12 @@ void drm_atomic_connector_apply_commit(struct wlr_drm_connector_state *state) { if (state->primary_in_fence_fd >= 0) { close(state->primary_in_fence_fd); } + if (state->out_fence_fd >= 0) { + // TODO: error handling + wlr_drm_syncobj_timeline_import_sync_file(state->base->signal_timeline, + state->base->signal_point, state->out_fence_fd); + close(state->out_fence_fd); + } conn->colorspace = state->colorspace; } @@ -441,6 +446,9 @@ void drm_atomic_connector_rollback_commit(struct wlr_drm_connector_state *state) if (state->primary_in_fence_fd >= 0) { close(state->primary_in_fence_fd); } + if (state->out_fence_fd >= 0) { + close(state->out_fence_fd); + } } static void plane_disable(struct atomic *atom, struct wlr_drm_plane *plane) { @@ -476,62 +484,6 @@ static void set_plane_props(struct atomic *atom, struct wlr_drm_backend *drm, atomic_add(atom, id, props->crtc_h, dst_box->height); } -static void set_color_encoding_and_range(struct atomic *atom, - struct wlr_drm_backend *drm, struct wlr_drm_plane *plane, - enum wlr_color_encoding encoding, enum wlr_color_range range) { - uint32_t id = plane->id; - const struct wlr_drm_plane_props *props = &plane->props; - - uint32_t color_encoding; - switch (encoding) { - case WLR_COLOR_ENCODING_NONE: - case WLR_COLOR_ENCODING_BT601: - color_encoding = WLR_DRM_COLOR_YCBCR_BT601; - break; - case WLR_COLOR_ENCODING_BT709: - color_encoding = WLR_DRM_COLOR_YCBCR_BT709; - break; - case WLR_COLOR_ENCODING_BT2020: - color_encoding = WLR_DRM_COLOR_YCBCR_BT2020; - break; - default: - wlr_log(WLR_DEBUG, "Unsupported color encoding %d", encoding); - atom->failed = true; - return; - } - - if (props->color_encoding) { - atomic_add(atom, id, props->color_encoding, color_encoding); - } else { - wlr_log(WLR_DEBUG, "Plane %"PRIu32" is missing the COLOR_ENCODING property", - id); - atom->failed = true; - return; - } - - uint32_t color_range; - switch (range) { - case WLR_COLOR_RANGE_NONE: - case WLR_COLOR_RANGE_LIMITED: - color_range = WLR_DRM_COLOR_YCBCR_LIMITED_RANGE; - break; - case WLR_COLOR_RANGE_FULL: - color_range = WLR_DRM_COLOR_YCBCR_FULL_RANGE; - break; - default: - assert(0); // Unreachable - } - - if (props->color_range) { - atomic_add(atom, id, props->color_range, color_range); - } else { - wlr_log(WLR_DEBUG, "Plane %"PRIu32" is missing the COLOR_RANGE property", - id); - atom->failed = true; - return; - } -} - static bool supports_cursor_hotspots(const struct wlr_drm_plane *plane) { return plane->props.hotspot_x && plane->props.hotspot_y; } @@ -548,6 +500,19 @@ static void set_plane_in_fence_fd(struct atomic *atom, atomic_add(atom, plane->id, plane->props.in_fence_fd, sync_file_fd); } +static void set_crtc_out_fence_ptr(struct atomic *atom, struct wlr_drm_crtc *crtc, + int *fd_ptr) { + if (!crtc->props.out_fence_ptr) { + wlr_log(WLR_ERROR, + "CRTC %"PRIu32" is missing the OUT_FENCE_PTR property", + crtc->id); + atom->failed = true; + return; + } + + atomic_add(atom, crtc->id, crtc->props.out_fence_ptr, (uintptr_t)fd_ptr); +} + static void atomic_connector_add(struct atomic *atom, struct wlr_drm_connector_state *state, bool modeset) { struct wlr_drm_connector *conn = state->connector; @@ -585,10 +550,6 @@ static void atomic_connector_add(struct atomic *atom, set_plane_props(atom, drm, crtc->primary, state->primary_fb, crtc->id, &state->primary_viewport.dst_box, &state->primary_viewport.src_box); - if (state->base->committed & WLR_OUTPUT_STATE_COLOR_REPRESENTATION) { - set_color_encoding_and_range(atom, drm, crtc->primary, - state->base->color_encoding, state->base->color_range); - } if (crtc->primary->props.fb_damage_clips != 0) { atomic_add(atom, crtc->primary->id, crtc->primary->props.fb_damage_clips, state->fb_damage_clips); @@ -596,6 +557,9 @@ static void atomic_connector_add(struct atomic *atom, if (state->primary_in_fence_fd >= 0) { set_plane_in_fence_fd(atom, crtc->primary, state->primary_in_fence_fd); } + if (state->base->committed & WLR_OUTPUT_STATE_SIGNAL_TIMELINE) { + set_crtc_out_fence_ptr(atom, crtc, &state->out_fence_fd); + } if (crtc->cursor) { if (drm_connector_is_cursor_visible(conn)) { struct wlr_fbox cursor_src = { diff --git a/backend/drm/backend.c b/backend/drm/backend.c index c2806152b..5a545b192 100644 --- a/backend/drm/backend.c +++ b/backend/drm/backend.c @@ -95,7 +95,7 @@ static const struct wlr_backend_impl backend_impl = { .commit = backend_commit, }; -bool wlr_backend_is_drm(const struct wlr_backend *b) { +bool wlr_backend_is_drm(struct wlr_backend *b) { return b->impl == &backend_impl; } diff --git a/backend/drm/drm.c b/backend/drm/drm.c index d2f75f71f..86b52c684 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -43,8 +43,7 @@ static const uint32_t COMMIT_OUTPUT_STATE = WLR_OUTPUT_STATE_WAIT_TIMELINE | WLR_OUTPUT_STATE_SIGNAL_TIMELINE | WLR_OUTPUT_STATE_COLOR_TRANSFORM | - WLR_OUTPUT_STATE_IMAGE_DESCRIPTION | - WLR_OUTPUT_STATE_COLOR_REPRESENTATION; + WLR_OUTPUT_STATE_IMAGE_DESCRIPTION; static const uint32_t SUPPORTED_OUTPUT_STATE = WLR_OUTPUT_STATE_BACKEND_OPTIONAL | COMMIT_OUTPUT_STATE; @@ -368,17 +367,7 @@ static void drm_plane_finish_surface(struct wlr_drm_plane *plane) { } drm_fb_clear(&plane->queued_fb); - if (plane->queued_release_timeline != NULL) { - wlr_drm_syncobj_timeline_signal(plane->queued_release_timeline, plane->queued_release_point); - wlr_drm_syncobj_timeline_unref(plane->queued_release_timeline); - plane->queued_release_timeline = NULL; - } drm_fb_clear(&plane->current_fb); - if (plane->current_release_timeline != NULL) { - wlr_drm_syncobj_timeline_signal(plane->current_release_timeline, plane->current_release_point); - wlr_drm_syncobj_timeline_unref(plane->current_release_timeline); - plane->current_release_timeline = NULL; - } finish_drm_surface(&plane->mgpu_surf); } @@ -567,18 +556,6 @@ static void drm_connector_apply_commit(const struct wlr_drm_connector_state *sta struct wlr_drm_crtc *crtc = conn->crtc; drm_fb_copy(&crtc->primary->queued_fb, state->primary_fb); - if (crtc->primary->queued_release_timeline != NULL) { - wlr_drm_syncobj_timeline_signal(crtc->primary->queued_release_timeline, crtc->primary->queued_release_point); - wlr_drm_syncobj_timeline_unref(crtc->primary->queued_release_timeline); - } - if (state->base->signal_timeline != NULL) { - crtc->primary->queued_release_timeline = wlr_drm_syncobj_timeline_ref(state->base->signal_timeline); - crtc->primary->queued_release_point = state->base->signal_point; - } else { - crtc->primary->queued_release_timeline = NULL; - crtc->primary->queued_release_point = 0; - } - crtc->primary->viewport = state->primary_viewport; if (crtc->cursor != NULL) { drm_fb_copy(&crtc->cursor->queued_fb, state->cursor_fb); @@ -669,6 +646,7 @@ static void drm_connector_state_init(struct wlr_drm_connector_state *state, .base = base, .active = output_pending_enabled(&conn->output, base), .primary_in_fence_fd = -1, + .out_fence_fd = -1, }; struct wlr_output_mode *mode = conn->output.current_mode; @@ -1321,7 +1299,7 @@ static const struct wlr_output_impl output_impl = { .get_primary_formats = drm_connector_get_primary_formats, }; -bool wlr_output_is_drm(const struct wlr_output *output) { +bool wlr_output_is_drm(struct wlr_output *output) { return output->impl == &output_impl; } @@ -2040,14 +2018,6 @@ static void handle_page_flip(int fd, unsigned seq, struct wlr_drm_plane *plane = conn->crtc->primary; if (plane->queued_fb) { drm_fb_move(&plane->current_fb, &plane->queued_fb); - if (plane->current_release_timeline != NULL) { - wlr_drm_syncobj_timeline_signal(plane->current_release_timeline, plane->current_release_point); - wlr_drm_syncobj_timeline_unref(plane->current_release_timeline); - } - plane->current_release_timeline = plane->queued_release_timeline; - plane->current_release_point = plane->queued_release_point; - plane->queued_release_timeline = NULL; - plane->queued_release_point = 0; } if (conn->crtc->cursor && conn->crtc->cursor->queued_fb) { drm_fb_move(&conn->crtc->cursor->current_fb, @@ -2134,7 +2104,6 @@ int wlr_drm_backend_get_non_master_fd(struct wlr_backend *backend) { if (drmIsMaster(fd) && drmDropMaster(fd) < 0) { wlr_log_errno(WLR_ERROR, "Failed to drop master"); - close(fd); return -1; } @@ -2169,7 +2138,7 @@ struct wlr_drm_lease *wlr_drm_create_lease(struct wlr_output **outputs, wlr_log(WLR_DEBUG, "Connector %d", conn->id); if (!drm_connector_alloc_crtc(conn)) { - wlr_log(WLR_ERROR, "Failed to allocate connector CRTC"); + wlr_log(WLR_ERROR, "Failled to allocate connector CRTC"); return NULL; } diff --git a/backend/drm/libliftoff.c b/backend/drm/libliftoff.c index 333beacad..12761afd4 100644 --- a/backend/drm/libliftoff.c +++ b/backend/drm/libliftoff.c @@ -352,6 +352,10 @@ static bool add_connector(drmModeAtomicReq *req, liftoff_layer_set_property(crtc->liftoff_composition_layer, "IN_FENCE_FD", state->primary_in_fence_fd); } + if (state->base->committed & WLR_OUTPUT_STATE_SIGNAL_TIMELINE) { + ok = ok && add_prop(req, crtc->id, crtc->props.out_fence_ptr, + (uintptr_t)&state->out_fence_fd); + } if (state->base->committed & WLR_OUTPUT_STATE_LAYERS) { for (size_t i = 0; i < state->base->layers_len; i++) { diff --git a/backend/drm/properties.c b/backend/drm/properties.c index 4c6bdcb36..314023954 100644 --- a/backend/drm/properties.c +++ b/backend/drm/properties.c @@ -50,8 +50,6 @@ static const struct prop_info crtc_info[] = { static const struct prop_info plane_info[] = { #define INDEX(name) (offsetof(struct wlr_drm_plane_props, name) / sizeof(uint32_t)) - { "COLOR_ENCODING", INDEX(color_encoding) }, - { "COLOR_RANGE", INDEX(color_range) }, { "CRTC_H", INDEX(crtc_h) }, { "CRTC_ID", INDEX(crtc_id) }, { "CRTC_W", INDEX(crtc_w) }, diff --git a/backend/headless/backend.c b/backend/headless/backend.c index 0f21b53f4..d03f520b8 100644 --- a/backend/headless/backend.c +++ b/backend/headless/backend.c @@ -81,6 +81,6 @@ struct wlr_backend *wlr_headless_backend_create(struct wl_event_loop *loop) { return &backend->backend; } -bool wlr_backend_is_headless(const struct wlr_backend *backend) { +bool wlr_backend_is_headless(struct wlr_backend *backend) { return backend->impl == &backend_impl; } diff --git a/backend/headless/output.c b/backend/headless/output.c index 0464e0d1b..a4cdb17c3 100644 --- a/backend/headless/output.c +++ b/backend/headless/output.c @@ -106,7 +106,7 @@ static const struct wlr_output_impl output_impl = { .move_cursor = output_move_cursor, }; -bool wlr_output_is_headless(const struct wlr_output *wlr_output) { +bool wlr_output_is_headless(struct wlr_output *wlr_output) { return wlr_output->impl == &output_impl; } diff --git a/backend/libinput/backend.c b/backend/libinput/backend.c index 0c72c6849..121731b31 100644 --- a/backend/libinput/backend.c +++ b/backend/libinput/backend.c @@ -155,7 +155,7 @@ static const struct wlr_backend_impl backend_impl = { .destroy = backend_destroy, }; -bool wlr_backend_is_libinput(const struct wlr_backend *b) { +bool wlr_backend_is_libinput(struct wlr_backend *b) { return b->impl == &backend_impl; } diff --git a/backend/libinput/events.c b/backend/libinput/events.c index 9be5def87..6cfe34e08 100644 --- a/backend/libinput/events.c +++ b/backend/libinput/events.c @@ -249,15 +249,3 @@ void handle_libinput_event(struct wlr_libinput_backend *backend, break; } } - -bool button_state_from_libinput(enum libinput_button_state state, enum wlr_button_state *out) { - switch (state) { - case LIBINPUT_BUTTON_STATE_RELEASED: - *out = WLR_BUTTON_RELEASED; - return true; - case LIBINPUT_BUTTON_STATE_PRESSED: - *out = WLR_BUTTON_PRESSED; - return true; - } - return false; -} diff --git a/backend/libinput/keyboard.c b/backend/libinput/keyboard.c index a99461040..7518453e6 100644 --- a/backend/libinput/keyboard.c +++ b/backend/libinput/keyboard.c @@ -2,7 +2,6 @@ #include #include #include -#include #include "backend/libinput.h" struct wlr_libinput_input_device *device_from_keyboard( @@ -31,18 +30,6 @@ void init_device_keyboard(struct wlr_libinput_input_device *dev) { libinput_device_led_update(dev->handle, 0); } -static bool key_state_from_libinput(enum libinput_key_state state, enum wl_keyboard_key_state *out) { - switch (state) { - case LIBINPUT_KEY_STATE_RELEASED: - *out = WL_KEYBOARD_KEY_STATE_RELEASED; - return true; - case LIBINPUT_KEY_STATE_PRESSED: - *out = WL_KEYBOARD_KEY_STATE_PRESSED; - return true; - } - return false; -} - void handle_keyboard_key(struct libinput_event *event, struct wlr_keyboard *kb) { struct libinput_event_keyboard *kbevent = @@ -52,9 +39,13 @@ void handle_keyboard_key(struct libinput_event *event, .keycode = libinput_event_keyboard_get_key(kbevent), .update_state = true, }; - if (!key_state_from_libinput(libinput_event_keyboard_get_key_state(kbevent), &wlr_event.state)) { - wlr_log(WLR_DEBUG, "Unhandled libinput key state"); - return; + switch (libinput_event_keyboard_get_key_state(kbevent)) { + case LIBINPUT_KEY_STATE_RELEASED: + wlr_event.state = WL_KEYBOARD_KEY_STATE_RELEASED; + break; + case LIBINPUT_KEY_STATE_PRESSED: + wlr_event.state = WL_KEYBOARD_KEY_STATE_PRESSED; + break; } wlr_keyboard_notify_key(kb, &wlr_event); } diff --git a/backend/libinput/meson.build b/backend/libinput/meson.build index 091b0e0eb..c244eb77a 100644 --- a/backend/libinput/meson.build +++ b/backend/libinput/meson.build @@ -29,7 +29,3 @@ features += { 'libinput-backend': true } wlr_deps += libinput internal_config.set10('HAVE_LIBINPUT_BUSTYPE', libinput.version().version_compare('>=1.26.0')) -internal_config.set10( - 'HAVE_LIBINPUT_SWITCH_KEYPAD_SLIDE', - libinput.version().version_compare('>=1.30.901') -) diff --git a/backend/libinput/pointer.c b/backend/libinput/pointer.c index d09164a71..9b9996780 100644 --- a/backend/libinput/pointer.c +++ b/backend/libinput/pointer.c @@ -1,7 +1,6 @@ #include #include #include -#include #include "backend/libinput.h" const struct wlr_pointer_impl libinput_pointer_impl = { @@ -53,38 +52,6 @@ void handle_pointer_motion_abs(struct libinput_event *event, wl_signal_emit_mutable(&pointer->events.frame, pointer); } -static bool pointer_button_state_from_libinput(enum libinput_button_state state, - enum wl_pointer_button_state *out) { - switch (state) { - case LIBINPUT_BUTTON_STATE_PRESSED: - *out = WL_POINTER_BUTTON_STATE_PRESSED; - return true; - case LIBINPUT_BUTTON_STATE_RELEASED: - *out = WL_POINTER_BUTTON_STATE_RELEASED; - return true; - } - return false; -} - -static bool axis_source_from_libinput(enum libinput_pointer_axis_source source, - enum wl_pointer_axis_source *out) { - switch (source) { - case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL: - *out = WL_POINTER_AXIS_SOURCE_WHEEL; - return true; - case LIBINPUT_POINTER_AXIS_SOURCE_FINGER: - *out = WL_POINTER_AXIS_SOURCE_FINGER; - return true; - case LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS: - *out = WL_POINTER_AXIS_SOURCE_CONTINUOUS; - return true; - case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL_TILT: - *out = WL_POINTER_AXIS_SOURCE_WHEEL_TILT; - return true; - } - return false; -} - void handle_pointer_button(struct libinput_event *event, struct wlr_pointer *pointer) { struct libinput_event_pointer *pevent = @@ -94,10 +61,13 @@ void handle_pointer_button(struct libinput_event *event, .time_msec = usec_to_msec(libinput_event_pointer_get_time_usec(pevent)), .button = libinput_event_pointer_get_button(pevent), }; - if (!pointer_button_state_from_libinput(libinput_event_pointer_get_button_state(pevent), - &wlr_event.state)) { - wlr_log(WLR_DEBUG, "Unhandled libinput button state"); - return; + switch (libinput_event_pointer_get_button_state(pevent)) { + case LIBINPUT_BUTTON_STATE_PRESSED: + wlr_event.state = WL_POINTER_BUTTON_STATE_PRESSED; + break; + case LIBINPUT_BUTTON_STATE_RELEASED: + wlr_event.state = WL_POINTER_BUTTON_STATE_RELEASED; + break; } wlr_pointer_notify_button(pointer, &wlr_event); wl_signal_emit_mutable(&pointer->events.frame, pointer); @@ -111,9 +81,19 @@ void handle_pointer_axis(struct libinput_event *event, .pointer = pointer, .time_msec = usec_to_msec(libinput_event_pointer_get_time_usec(pevent)), }; - if (!axis_source_from_libinput(libinput_event_pointer_get_axis_source(pevent), &wlr_event.source)) { - wlr_log(WLR_DEBUG, "Unhandled libinput pointer axis source"); - return; + switch (libinput_event_pointer_get_axis_source(pevent)) { + case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL: + wlr_event.source = WL_POINTER_AXIS_SOURCE_WHEEL; + break; + case LIBINPUT_POINTER_AXIS_SOURCE_FINGER: + wlr_event.source = WL_POINTER_AXIS_SOURCE_FINGER; + break; + case LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS: + wlr_event.source = WL_POINTER_AXIS_SOURCE_CONTINUOUS; + break; + case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL_TILT: + wlr_event.source = WL_POINTER_AXIS_SOURCE_WHEEL_TILT; + break; } const enum libinput_pointer_axis axes[] = { LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, diff --git a/backend/libinput/switch.c b/backend/libinput/switch.c index 2055d88f5..abeec86d7 100644 --- a/backend/libinput/switch.c +++ b/backend/libinput/switch.c @@ -1,9 +1,7 @@ #include #include #include -#include #include "backend/libinput.h" -#include "config.h" const struct wlr_switch_impl libinput_switch_impl = { .name = "libinput-switch", @@ -24,49 +22,28 @@ struct wlr_libinput_input_device *device_from_switch( return dev; } -static bool switch_type_from_libinput(enum libinput_switch type, enum wlr_switch_type *out) { - switch (type) { - case LIBINPUT_SWITCH_LID: - *out = WLR_SWITCH_TYPE_LID; - return true; - case LIBINPUT_SWITCH_TABLET_MODE: - *out = WLR_SWITCH_TYPE_TABLET_MODE; - return true; -#if HAVE_LIBINPUT_SWITCH_KEYPAD_SLIDE - case LIBINPUT_SWITCH_KEYPAD_SLIDE: - *out = WLR_SWITCH_TYPE_KEYPAD_SLIDE; - return true; -#endif - } - return false; -} - -static bool switch_state_from_libinput(enum libinput_switch_state state, enum wlr_switch_state *out) { - switch (state) { - case LIBINPUT_SWITCH_STATE_OFF: - *out = WLR_SWITCH_STATE_OFF; - return true; - case LIBINPUT_SWITCH_STATE_ON: - *out = WLR_SWITCH_STATE_ON; - return true; - } - return false; -} - void handle_switch_toggle(struct libinput_event *event, struct wlr_switch *wlr_switch) { struct libinput_event_switch *sevent = - libinput_event_get_switch_event(event); + libinput_event_get_switch_event (event); struct wlr_switch_toggle_event wlr_event = { .time_msec = usec_to_msec(libinput_event_switch_get_time_usec(sevent)), }; - if (!switch_type_from_libinput(libinput_event_switch_get_switch(sevent), &wlr_event.switch_type)) { - wlr_log(WLR_DEBUG, "Unhandled libinput switch type"); - return; + switch (libinput_event_switch_get_switch(sevent)) { + case LIBINPUT_SWITCH_LID: + wlr_event.switch_type = WLR_SWITCH_TYPE_LID; + break; + case LIBINPUT_SWITCH_TABLET_MODE: + wlr_event.switch_type = WLR_SWITCH_TYPE_TABLET_MODE; + break; } - if (!switch_state_from_libinput(libinput_event_switch_get_switch_state(sevent), &wlr_event.switch_state)) { - wlr_log(WLR_DEBUG, "Unhandled libinput switch state"); - return; + switch (libinput_event_switch_get_switch_state(sevent)) { + case LIBINPUT_SWITCH_STATE_OFF: + wlr_event.switch_state = WLR_SWITCH_STATE_OFF; + break; + case LIBINPUT_SWITCH_STATE_ON: + wlr_event.switch_state = WLR_SWITCH_STATE_ON; + break; } wl_signal_emit_mutable(&wlr_switch->events.toggle, &wlr_event); } diff --git a/backend/libinput/tablet_pad.c b/backend/libinput/tablet_pad.c index 9d090198a..2fbfb6a6c 100644 --- a/backend/libinput/tablet_pad.c +++ b/backend/libinput/tablet_pad.c @@ -148,9 +148,13 @@ void handle_tablet_pad_button(struct libinput_event *event, .group = libinput_tablet_pad_mode_group_get_index( libinput_event_tablet_pad_get_mode_group(pevent)), }; - if (!button_state_from_libinput(libinput_event_tablet_pad_get_button_state(pevent), &wlr_event.state)) { - wlr_log(WLR_DEBUG, "Unhandled libinput button state"); - return; + switch (libinput_event_tablet_pad_get_button_state(pevent)) { + case LIBINPUT_BUTTON_STATE_PRESSED: + wlr_event.state = WLR_BUTTON_PRESSED; + break; + case LIBINPUT_BUTTON_STATE_RELEASED: + wlr_event.state = WLR_BUTTON_RELEASED; + break; } wl_signal_emit_mutable(&tablet_pad->events.button, &wlr_event); } @@ -164,7 +168,6 @@ void handle_tablet_pad_ring(struct libinput_event *event, .ring = libinput_event_tablet_pad_get_ring_number(pevent), .position = libinput_event_tablet_pad_get_ring_position(pevent), .mode = libinput_event_tablet_pad_get_mode(pevent), - .source = WLR_TABLET_PAD_RING_SOURCE_UNKNOWN, }; switch (libinput_event_tablet_pad_get_ring_source(pevent)) { case LIBINPUT_TABLET_PAD_RING_SOURCE_UNKNOWN: @@ -186,7 +189,6 @@ void handle_tablet_pad_strip(struct libinput_event *event, .strip = libinput_event_tablet_pad_get_strip_number(pevent), .position = libinput_event_tablet_pad_get_strip_position(pevent), .mode = libinput_event_tablet_pad_get_mode(pevent), - .source = WLR_TABLET_PAD_STRIP_SOURCE_UNKNOWN, }; switch (libinput_event_tablet_pad_get_strip_source(pevent)) { case LIBINPUT_TABLET_PAD_STRIP_SOURCE_UNKNOWN: diff --git a/backend/libinput/tablet_tool.c b/backend/libinput/tablet_tool.c index 782e56a86..b2430a445 100644 --- a/backend/libinput/tablet_tool.c +++ b/backend/libinput/tablet_tool.c @@ -78,61 +78,27 @@ struct wlr_libinput_input_device *device_from_tablet( return dev; } -static bool type_from_libinput(enum libinput_tablet_tool_type type, - enum wlr_tablet_tool_type *out) { - switch (type) { +static enum wlr_tablet_tool_type wlr_type_from_libinput_type( + enum libinput_tablet_tool_type value) { + switch (value) { case LIBINPUT_TABLET_TOOL_TYPE_PEN: - *out = WLR_TABLET_TOOL_TYPE_PEN; - return true; + return WLR_TABLET_TOOL_TYPE_PEN; case LIBINPUT_TABLET_TOOL_TYPE_ERASER: - *out = WLR_TABLET_TOOL_TYPE_ERASER; - return true; + return WLR_TABLET_TOOL_TYPE_ERASER; case LIBINPUT_TABLET_TOOL_TYPE_BRUSH: - *out = WLR_TABLET_TOOL_TYPE_BRUSH; - return true; + return WLR_TABLET_TOOL_TYPE_BRUSH; case LIBINPUT_TABLET_TOOL_TYPE_PENCIL: - *out = WLR_TABLET_TOOL_TYPE_PENCIL; - return true; + return WLR_TABLET_TOOL_TYPE_PENCIL; case LIBINPUT_TABLET_TOOL_TYPE_AIRBRUSH: - *out = WLR_TABLET_TOOL_TYPE_AIRBRUSH; - return true; + return WLR_TABLET_TOOL_TYPE_AIRBRUSH; case LIBINPUT_TABLET_TOOL_TYPE_MOUSE: - *out = WLR_TABLET_TOOL_TYPE_MOUSE; - return true; + return WLR_TABLET_TOOL_TYPE_MOUSE; case LIBINPUT_TABLET_TOOL_TYPE_LENS: - *out = WLR_TABLET_TOOL_TYPE_LENS; - return true; + return WLR_TABLET_TOOL_TYPE_LENS; case LIBINPUT_TABLET_TOOL_TYPE_TOTEM: - *out = WLR_TABLET_TOOL_TYPE_TOTEM; - return true; + return WLR_TABLET_TOOL_TYPE_TOTEM; } - return false; -} - -static bool proximity_state_from_libinput(enum libinput_tablet_tool_proximity_state state, - enum wlr_tablet_tool_proximity_state *out) { - switch (state) { - case LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT: - *out = WLR_TABLET_TOOL_PROXIMITY_OUT; - return true; - case LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN: - *out = WLR_TABLET_TOOL_PROXIMITY_IN; - return true; - } - return false; -} - -static bool tip_state_from_libinput(enum libinput_tablet_tool_tip_state state, - enum wlr_tablet_tool_tip_state *out) { - switch (state) { - case LIBINPUT_TABLET_TOOL_TIP_UP: - *out = WLR_TABLET_TOOL_TIP_UP; - return true; - case LIBINPUT_TABLET_TOOL_TIP_DOWN: - *out = WLR_TABLET_TOOL_TIP_DOWN; - return true; - } - return false; + abort(); // unreachable } static struct tablet_tool *get_tablet_tool( @@ -144,19 +110,14 @@ static struct tablet_tool *get_tablet_tool( return tool; } - enum wlr_tablet_tool_type type; - if (!type_from_libinput(libinput_tablet_tool_get_type(libinput_tool), &type)) { - wlr_log(WLR_DEBUG, "Unhandled libinput tablet tool type"); - return NULL; - } - tool = calloc(1, sizeof(*tool)); if (tool == NULL) { wlr_log_errno(WLR_ERROR, "failed to allocate wlr_libinput_tablet_tool"); return NULL; } - tool->wlr_tool.type = type; + tool->wlr_tool.type = wlr_type_from_libinput_type( + libinput_tablet_tool_get_type(libinput_tool)); tool->wlr_tool.hardware_serial = libinput_tablet_tool_get_serial(libinput_tool); tool->wlr_tool.hardware_wacom = @@ -248,12 +209,14 @@ void handle_tablet_tool_proximity(struct libinput_event *event, .y = libinput_event_tablet_tool_get_y_transformed(tevent, 1), }; - if (!proximity_state_from_libinput(libinput_event_tablet_tool_get_proximity_state(tevent), - &wlr_event.state)) { - wlr_log(WLR_DEBUG, "Unhandled libinput tablet tool proximity state"); - return; + switch (libinput_event_tablet_tool_get_proximity_state(tevent)) { + case LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT: + wlr_event.state = WLR_TABLET_TOOL_PROXIMITY_OUT; + break; + case LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN: + wlr_event.state = WLR_TABLET_TOOL_PROXIMITY_IN; + break; } - wl_signal_emit_mutable(&wlr_tablet->events.proximity, &wlr_event); if (libinput_event_tablet_tool_get_proximity_state(tevent) == @@ -288,11 +251,14 @@ void handle_tablet_tool_tip(struct libinput_event *event, .y = libinput_event_tablet_tool_get_y_transformed(tevent, 1), }; - if (!tip_state_from_libinput(libinput_event_tablet_tool_get_tip_state(tevent), &wlr_event.state)) { - wlr_log(WLR_DEBUG, "Unhandled libinput tablet tool tip state"); - return; + switch (libinput_event_tablet_tool_get_tip_state(tevent)) { + case LIBINPUT_TABLET_TOOL_TIP_UP: + wlr_event.state = WLR_TABLET_TOOL_TIP_UP; + break; + case LIBINPUT_TABLET_TOOL_TIP_DOWN: + wlr_event.state = WLR_TABLET_TOOL_TIP_DOWN; + break; } - wl_signal_emit_mutable(&wlr_tablet->events.tip, &wlr_event); } @@ -311,11 +277,13 @@ void handle_tablet_tool_button(struct libinput_event *event, .time_msec = usec_to_msec(libinput_event_tablet_tool_get_time_usec(tevent)), .button = libinput_event_tablet_tool_get_button(tevent), }; - - if (!button_state_from_libinput(libinput_event_tablet_tool_get_button_state(tevent), &wlr_event.state)) { - wlr_log(WLR_DEBUG, "Unhandled libinput button state"); - return; + switch (libinput_event_tablet_tool_get_button_state(tevent)) { + case LIBINPUT_BUTTON_STATE_RELEASED: + wlr_event.state = WLR_BUTTON_RELEASED; + break; + case LIBINPUT_BUTTON_STATE_PRESSED: + wlr_event.state = WLR_BUTTON_PRESSED; + break; } - wl_signal_emit_mutable(&wlr_tablet->events.button, &wlr_event); } diff --git a/backend/multi/backend.c b/backend/multi/backend.c index 3a9aca7e6..3d8fb96f5 100644 --- a/backend/multi/backend.c +++ b/backend/multi/backend.c @@ -173,7 +173,7 @@ struct wlr_backend *wlr_multi_backend_create(struct wl_event_loop *loop) { return &backend->backend; } -bool wlr_backend_is_multi(const struct wlr_backend *b) { +bool wlr_backend_is_multi(struct wlr_backend *b) { return b->impl == &backend_impl; } diff --git a/backend/wayland/backend.c b/backend/wayland/backend.c index 0d294b543..14a783b67 100644 --- a/backend/wayland/backend.c +++ b/backend/wayland/backend.c @@ -577,7 +577,7 @@ static const struct wlr_backend_impl backend_impl = { .get_drm_fd = backend_get_drm_fd, }; -bool wlr_backend_is_wl(const struct wlr_backend *b) { +bool wlr_backend_is_wl(struct wlr_backend *b) { return b->impl == &backend_impl; } diff --git a/backend/wayland/output.c b/backend/wayland/output.c index c3442f411..fb4d1f914 100644 --- a/backend/wayland/output.c +++ b/backend/wayland/output.c @@ -1027,7 +1027,7 @@ static const struct wlr_output_impl output_impl = { .get_primary_formats = output_get_formats, }; -bool wlr_output_is_wl(const struct wlr_output *wlr_output) { +bool wlr_output_is_wl(struct wlr_output *wlr_output) { return wlr_output->impl == &output_impl; } diff --git a/backend/wayland/seat.c b/backend/wayland/seat.c index f178d9baf..a66357bf8 100644 --- a/backend/wayland/seat.c +++ b/backend/wayland/seat.c @@ -246,7 +246,7 @@ void init_seat_touch(struct wlr_wl_seat *seat) { struct wlr_wl_output *output; wl_list_for_each(output, &seat->backend->outputs, link) { - /* Multi-output touch not supported */ + /* Multi-output touch not supproted */ seat->wlr_touch.output_name = strdup(output->wlr_output.name); break; } diff --git a/backend/x11/backend.c b/backend/x11/backend.c index de22faa0e..0983bad0a 100644 --- a/backend/x11/backend.c +++ b/backend/x11/backend.c @@ -115,7 +115,6 @@ static void handle_x11_event(struct wlr_x11_backend *x11, handle_x11_error(x11, ev); break; } - case XCB_DESTROY_NOTIFY: case XCB_UNMAP_NOTIFY: case XCB_MAP_NOTIFY: break; @@ -219,7 +218,7 @@ static const struct wlr_backend_impl backend_impl = { .get_drm_fd = backend_get_drm_fd, }; -bool wlr_backend_is_x11(const struct wlr_backend *backend) { +bool wlr_backend_is_x11(struct wlr_backend *backend) { return backend->impl == &backend_impl; } diff --git a/backend/x11/output.c b/backend/x11/output.c index 40e601f0b..0b63a7088 100644 --- a/backend/x11/output.c +++ b/backend/x11/output.c @@ -19,9 +19,7 @@ #include #include "backend/x11.h" -#include "render/pixel_format.h" #include "util/time.h" -#include "types/wlr_buffer.h" #include "types/wlr_output.h" static const uint32_t SUPPORTED_OUTPUT_STATE = @@ -168,20 +166,18 @@ static bool output_test(struct wlr_output *wlr_output, if (state->committed & WLR_OUTPUT_STATE_BUFFER) { struct wlr_buffer *buffer = state->buffer; - uint32_t format = buffer_get_drm_format(buffer); + struct wlr_dmabuf_attributes dmabuf_attrs; + struct wlr_shm_attributes shm_attrs; + uint32_t format = DRM_FORMAT_INVALID; + if (wlr_buffer_get_dmabuf(buffer, &dmabuf_attrs)) { + format = dmabuf_attrs.format; + } else if (wlr_buffer_get_shm(buffer, &shm_attrs)) { + format = shm_attrs.format; + } if (format != x11->x11_format->drm) { wlr_log(WLR_DEBUG, "Unsupported buffer format"); return false; } - struct wlr_shm_attributes shm; - if (wlr_buffer_get_shm(buffer, &shm)) { - const struct wlr_pixel_format_info *info = drm_get_pixel_format_info(format); - if (shm.stride != pixel_format_info_min_stride(info, shm.width)) { - // xcb_shm_create_pixmap() does not allow arbitrary strides. - wlr_log(WLR_DEBUG, "Unsupported shm buffer stride"); - return false; - } - } } if (state->committed & WLR_OUTPUT_STATE_MODE) { @@ -271,12 +267,6 @@ static xcb_pixmap_t import_shm(struct wlr_x11_output *output, return XCB_PIXMAP_NONE; } - const struct wlr_pixel_format_info *info = drm_get_pixel_format_info(shm->format); - if (shm->stride != pixel_format_info_min_stride(info, shm->width)) { - // xcb_shm_create_pixmap() does not allow arbitrary strides. - return XCB_PIXMAP_NONE; - } - // xcb closes the FD after sending it int fd = fcntl(shm->fd, F_DUPFD_CLOEXEC, 0); if (fd < 0) { @@ -711,7 +701,7 @@ void handle_x11_configure_notify(struct wlr_x11_output *output, wlr_output_state_finish(&state); } -bool wlr_output_is_x11(const struct wlr_output *wlr_output) { +bool wlr_output_is_x11(struct wlr_output *wlr_output) { return wlr_output->impl == &output_impl; } diff --git a/include/backend/drm/drm.h b/include/backend/drm/drm.h index a8c5e077a..af4231f54 100644 --- a/include/backend/drm/drm.h +++ b/include/backend/drm/drm.h @@ -29,12 +29,8 @@ struct wlr_drm_plane { /* Buffer submitted to the kernel, will be presented on next vblank */ struct wlr_drm_fb *queued_fb; - struct wlr_drm_syncobj_timeline *queued_release_timeline; - uint64_t queued_release_point; /* Buffer currently displayed on screen */ struct wlr_drm_fb *current_fb; - struct wlr_drm_syncobj_timeline *current_release_timeline; - uint64_t current_release_point; /* Viewport belonging to the last committed fb */ struct wlr_drm_viewport viewport; @@ -160,7 +156,7 @@ struct wlr_drm_connector_state { uint32_t mode_id; uint32_t gamma_lut; uint32_t fb_damage_clips; - int primary_in_fence_fd; + int primary_in_fence_fd, out_fence_fd; bool vrr_enabled; uint32_t colorspace; uint32_t hdr_output_metadata; diff --git a/include/backend/drm/properties.h b/include/backend/drm/properties.h index 20e0a5bff..c02d655ba 100644 --- a/include/backend/drm/properties.h +++ b/include/backend/drm/properties.h @@ -65,22 +65,6 @@ struct wlr_drm_plane_props { uint32_t hotspot_x; uint32_t hotspot_y; uint32_t in_fence_fd; - - uint32_t color_encoding; // Not guaranteed to exist - uint32_t color_range; // Not guaranteed to exist -}; - -// Equivalent to wlr_drm_color_encoding defined in the kernel (but not exported) -enum wlr_drm_color_encoding { - WLR_DRM_COLOR_YCBCR_BT601, - WLR_DRM_COLOR_YCBCR_BT709, - WLR_DRM_COLOR_YCBCR_BT2020, -}; - -// Equivalent to wlr_drm_color_range defined in the kernel (but not exported) -enum wlr_drm_color_range { - WLR_DRM_COLOR_YCBCR_FULL_RANGE, - WLR_DRM_COLOR_YCBCR_LIMITED_RANGE, }; bool get_drm_connector_props(int fd, uint32_t id, diff --git a/include/backend/libinput.h b/include/backend/libinput.h index e7123884e..874e9aa1f 100644 --- a/include/backend/libinput.h +++ b/include/backend/libinput.h @@ -132,6 +132,4 @@ void handle_tablet_pad_ring(struct libinput_event *event, void handle_tablet_pad_strip(struct libinput_event *event, struct wlr_tablet_pad *tablet_pad); -bool button_state_from_libinput(enum libinput_button_state state, enum wlr_button_state *out); - #endif diff --git a/include/render/color.h b/include/render/color.h index 60c841d12..57d2b6a96 100644 --- a/include/render/color.h +++ b/include/render/color.h @@ -91,7 +91,7 @@ struct wlr_color_transform_lut_3x1d *color_transform_lut_3x1d_from_base( * Create a simplified / normalized wlr_color_transform pipeline. * `transforms` may contain NULL transforms, they will be interpreted as the * identity transform, and removed. - * `*result` may be set to a transform of a type different from + * `*result` may be set to a tranform of a type different from * `wlr_color_transform_pipeline`, or to NULL if all input transforms are NULL */ bool color_transform_compose(struct wlr_color_transform **result, diff --git a/include/render/drm_syncobj_merger.h b/include/render/drm_syncobj_merger.h deleted file mode 100644 index c55c87314..000000000 --- a/include/render/drm_syncobj_merger.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef WLR_RENDER_DRM_SYNCOBJ_MERGER_H -#define WLR_RENDER_DRM_SYNCOBJ_MERGER_H - -#include - -/** - * Accumulate timeline points, to have a destination timeline point be - * signalled when all inputs are - */ -struct wlr_drm_syncobj_merger { - int n_ref; - struct wlr_drm_syncobj_timeline *dst_timeline; - uint64_t dst_point; - int sync_fd; -}; - -/** - * Create a new merger. - * - * The given timeline point will be signalled when all input points are - * signalled and the merger is destroyed. - */ -struct wlr_drm_syncobj_merger *wlr_drm_syncobj_merger_create( - struct wlr_drm_syncobj_timeline *dst_timeline, uint64_t dst_point); - -struct wlr_drm_syncobj_merger *wlr_drm_syncobj_merger_ref( - struct wlr_drm_syncobj_merger *merger); - -/** - * Target timeline point is materialized when all inputs are, and the merger is - * destroyed. - */ -void wlr_drm_syncobj_merger_unref(struct wlr_drm_syncobj_merger *merger); -/** - * Add a new timeline point to wait for. - * - * If the point is not materialized, the supplied event loop is used to schedule - * a wait. - */ -bool wlr_drm_syncobj_merger_add(struct wlr_drm_syncobj_merger *merger, - struct wlr_drm_syncobj_timeline *dst_timeline, uint64_t dst_point, - struct wl_event_loop *loop); - -#endif diff --git a/include/render/pixel_format.h b/include/render/pixel_format.h index b5f2b2411..e0b500c75 100644 --- a/include/render/pixel_format.h +++ b/include/render/pixel_format.h @@ -63,9 +63,4 @@ enum wl_shm_format convert_drm_format_to_wl_shm(uint32_t fmt); */ bool pixel_format_has_alpha(uint32_t fmt); -/** - * Return true if the DRM FourCC fmt belongs to a YCbCr colorspace family, false otherwise. - */ -bool pixel_format_is_ycbcr(uint32_t fmt); - #endif diff --git a/include/render/vulkan.h b/include/render/vulkan.h index c5d571ef7..bb56b5534 100644 --- a/include/render/vulkan.h +++ b/include/render/vulkan.h @@ -56,10 +56,6 @@ struct wlr_vk_device { PFN_vkGetSemaphoreFdKHR vkGetSemaphoreFdKHR; PFN_vkImportSemaphoreFdKHR vkImportSemaphoreFdKHR; PFN_vkQueueSubmit2KHR vkQueueSubmit2KHR; - PFN_vkBindImageMemory2KHR vkBindImageMemory2KHR; - PFN_vkCreateSamplerYcbcrConversionKHR vkCreateSamplerYcbcrConversionKHR; - PFN_vkDestroySamplerYcbcrConversionKHR vkDestroySamplerYcbcrConversionKHR; - PFN_vkGetImageMemoryRequirements2KHR vkGetImageMemoryRequirements2KHR; } api; uint32_t format_prop_count; @@ -90,6 +86,7 @@ struct wlr_vk_format { uint32_t drm; VkFormat vk; VkFormat vk_srgb; // sRGB version of the format, or 0 if nonexistent + bool is_ycbcr; }; extern const VkImageUsageFlags vulkan_render_usage, vulkan_shm_tex_usage, vulkan_dma_tex_usage; @@ -128,7 +125,6 @@ void vulkan_format_props_query(struct wlr_vk_device *dev, const struct wlr_vk_format_modifier_props *vulkan_format_props_find_modifier( const struct wlr_vk_format_props *props, uint64_t mod, bool render); void vulkan_format_props_finish(struct wlr_vk_format_props *props); -bool vulkan_format_is_ycbcr(const struct wlr_vk_format *format); struct wlr_vk_pipeline_layout_key { enum wlr_scale_filter_mode filter_mode; @@ -228,7 +224,7 @@ struct wlr_vk_render_buffer_out { bool transitioned; }; -// Renderer-internal representation of an wlr_buffer imported for rendering. +// Renderer-internal represenation of an wlr_buffer imported for rendering. struct wlr_vk_render_buffer { struct wlr_buffer *wlr_buffer; struct wlr_addon addon; @@ -477,11 +473,10 @@ void vulkan_reset_command_buffer(struct wlr_vk_command_buffer *cb); bool vulkan_wait_command_buffer(struct wlr_vk_command_buffer *cb, struct wlr_vk_renderer *renderer); -bool vulkan_sync_render_pass_release(struct wlr_vk_renderer *renderer, - struct wlr_vk_render_pass *pass); -bool vulkan_sync_foreign_texture_acquire(struct wlr_vk_texture *texture, - int sync_file_fds[static WLR_DMABUF_MAX_PLANES]); -bool vulkan_sync_render_buffer_acquire(struct wlr_vk_render_buffer *render_buffer, +bool vulkan_sync_render_buffer(struct wlr_vk_renderer *renderer, + struct wlr_vk_render_buffer *render_buffer, struct wlr_vk_command_buffer *cb, + struct wlr_drm_syncobj_timeline *signal_timeline, uint64_t signal_point); +bool vulkan_sync_foreign_texture(struct wlr_vk_texture *texture, int sync_file_fds[static WLR_DMABUF_MAX_PLANES]); bool vulkan_read_pixels(struct wlr_vk_renderer *vk_renderer, diff --git a/include/types/wlr_buffer.h b/include/types/wlr_buffer.h index 45acf7a1d..9d882d47d 100644 --- a/include/types/wlr_buffer.h +++ b/include/types/wlr_buffer.h @@ -65,10 +65,4 @@ struct wlr_client_buffer *wlr_client_buffer_create(struct wlr_buffer *buffer, bool wlr_client_buffer_apply_damage(struct wlr_client_buffer *client_buffer, struct wlr_buffer *next, const pixman_region32_t *damage); -/** - * Return the DRM format of the buffer. If this buffer isn't shared - * memory or a DMA-BUF, returns DRM_FORMAT_INVALID. - */ -uint32_t buffer_get_drm_format(struct wlr_buffer *buffer); - #endif diff --git a/include/wlr/backend/drm.h b/include/wlr/backend/drm.h index 233bbcb74..3ca6390ab 100644 --- a/include/wlr/backend/drm.h +++ b/include/wlr/backend/drm.h @@ -39,8 +39,8 @@ struct wlr_drm_lease { struct wlr_backend *wlr_drm_backend_create(struct wlr_session *session, struct wlr_device *dev, struct wlr_backend *parent); -bool wlr_backend_is_drm(const struct wlr_backend *backend); -bool wlr_output_is_drm(const struct wlr_output *output); +bool wlr_backend_is_drm(struct wlr_backend *backend); +bool wlr_output_is_drm(struct wlr_output *output); /** * Get the parent DRM backend, if any. diff --git a/include/wlr/backend/headless.h b/include/wlr/backend/headless.h index 5487c6085..126f1ff21 100644 --- a/include/wlr/backend/headless.h +++ b/include/wlr/backend/headless.h @@ -25,7 +25,7 @@ struct wlr_backend *wlr_headless_backend_create(struct wl_event_loop *loop); struct wlr_output *wlr_headless_add_output(struct wlr_backend *backend, unsigned int width, unsigned int height); -bool wlr_backend_is_headless(const struct wlr_backend *backend); -bool wlr_output_is_headless(const struct wlr_output *output); +bool wlr_backend_is_headless(struct wlr_backend *backend); +bool wlr_output_is_headless(struct wlr_output *output); #endif diff --git a/include/wlr/backend/libinput.h b/include/wlr/backend/libinput.h index cb5ef824d..2a4e1996e 100644 --- a/include/wlr/backend/libinput.h +++ b/include/wlr/backend/libinput.h @@ -29,7 +29,7 @@ struct libinput_device *wlr_libinput_get_device_handle( struct libinput_tablet_tool *wlr_libinput_get_tablet_tool_handle( struct wlr_tablet_tool *wlr_tablet_tool); -bool wlr_backend_is_libinput(const struct wlr_backend *backend); +bool wlr_backend_is_libinput(struct wlr_backend *backend); bool wlr_input_device_is_libinput(struct wlr_input_device *device); #endif diff --git a/include/wlr/backend/multi.h b/include/wlr/backend/multi.h index cc3e41b4e..c4322d98b 100644 --- a/include/wlr/backend/multi.h +++ b/include/wlr/backend/multi.h @@ -26,7 +26,7 @@ bool wlr_multi_backend_add(struct wlr_backend *multi, void wlr_multi_backend_remove(struct wlr_backend *multi, struct wlr_backend *backend); -bool wlr_backend_is_multi(const struct wlr_backend *backend); +bool wlr_backend_is_multi(struct wlr_backend *backend); bool wlr_multi_is_empty(struct wlr_backend *backend); void wlr_multi_for_each_backend(struct wlr_backend *backend, diff --git a/include/wlr/backend/wayland.h b/include/wlr/backend/wayland.h index 7a41b3d09..c732de68c 100644 --- a/include/wlr/backend/wayland.h +++ b/include/wlr/backend/wayland.h @@ -46,7 +46,7 @@ struct wlr_output *wlr_wl_output_create_from_surface(struct wlr_backend *backend /** * Check whether the provided backend is a Wayland backend. */ -bool wlr_backend_is_wl(const struct wlr_backend *backend); +bool wlr_backend_is_wl(struct wlr_backend *backend); /** * Check whether the provided input device is a Wayland input device. @@ -56,7 +56,7 @@ bool wlr_input_device_is_wl(struct wlr_input_device *device); /** * Check whether the provided output device is a Wayland output device. */ -bool wlr_output_is_wl(const struct wlr_output *output); +bool wlr_output_is_wl(struct wlr_output *output); /** * Sets the title of a struct wlr_output which is a Wayland toplevel. diff --git a/include/wlr/backend/x11.h b/include/wlr/backend/x11.h index 8e8bc9870..1791041ce 100644 --- a/include/wlr/backend/x11.h +++ b/include/wlr/backend/x11.h @@ -31,7 +31,7 @@ struct wlr_output *wlr_x11_output_create(struct wlr_backend *backend); /** * Check whether this backend is an X11 backend. */ -bool wlr_backend_is_x11(const struct wlr_backend *backend); +bool wlr_backend_is_x11(struct wlr_backend *backend); /** * Check whether this input device is an X11 input device. @@ -41,7 +41,7 @@ bool wlr_input_device_is_x11(struct wlr_input_device *device); /** * Check whether this output device is an X11 output device. */ -bool wlr_output_is_x11(const struct wlr_output *output); +bool wlr_output_is_x11(struct wlr_output *output); /** * Sets the title of a struct wlr_output which is an X11 window. diff --git a/include/wlr/render/drm_syncobj.h b/include/wlr/render/drm_syncobj.h index fabe23d1c..deef72dc9 100644 --- a/include/wlr/render/drm_syncobj.h +++ b/include/wlr/render/drm_syncobj.h @@ -90,10 +90,6 @@ bool wlr_drm_syncobj_timeline_transfer(struct wlr_drm_syncobj_timeline *dst, */ bool wlr_drm_syncobj_timeline_check(struct wlr_drm_syncobj_timeline *timeline, uint64_t point, uint32_t flags, bool *result); -/** - * Signals a timeline point. - */ -bool wlr_drm_syncobj_timeline_signal(struct wlr_drm_syncobj_timeline *timeline, uint64_t point); /** * Asynchronously wait for a timeline point. * diff --git a/include/wlr/render/gles2.h b/include/wlr/render/gles2.h index 87a57fa54..454e7eb0e 100644 --- a/include/wlr/render/gles2.h +++ b/include/wlr/render/gles2.h @@ -42,9 +42,9 @@ struct wlr_gles2_texture_attribs { bool has_alpha; }; -bool wlr_renderer_is_gles2(const struct wlr_renderer *wlr_renderer); -bool wlr_render_timer_is_gles2(const struct wlr_render_timer *timer); -bool wlr_texture_is_gles2(const struct wlr_texture *texture); +bool wlr_renderer_is_gles2(struct wlr_renderer *wlr_renderer); +bool wlr_render_timer_is_gles2(struct wlr_render_timer *timer); +bool wlr_texture_is_gles2(struct wlr_texture *texture); void wlr_gles2_texture_get_attribs(struct wlr_texture *texture, struct wlr_gles2_texture_attribs *attribs); diff --git a/include/wlr/render/pixman.h b/include/wlr/render/pixman.h index 2951f5e9e..206dd78c6 100644 --- a/include/wlr/render/pixman.h +++ b/include/wlr/render/pixman.h @@ -14,8 +14,8 @@ struct wlr_renderer *wlr_pixman_renderer_create(void); -bool wlr_renderer_is_pixman(const struct wlr_renderer *wlr_renderer); -bool wlr_texture_is_pixman(const struct wlr_texture *texture); +bool wlr_renderer_is_pixman(struct wlr_renderer *wlr_renderer); +bool wlr_texture_is_pixman(struct wlr_texture *texture); pixman_image_t *wlr_pixman_renderer_get_buffer_image( struct wlr_renderer *wlr_renderer, struct wlr_buffer *wlr_buffer); diff --git a/include/wlr/render/vulkan.h b/include/wlr/render/vulkan.h index 170665dd0..50f8c558d 100644 --- a/include/wlr/render/vulkan.h +++ b/include/wlr/render/vulkan.h @@ -25,8 +25,8 @@ VkPhysicalDevice wlr_vk_renderer_get_physical_device(struct wlr_renderer *render VkDevice wlr_vk_renderer_get_device(struct wlr_renderer *renderer); uint32_t wlr_vk_renderer_get_queue_family(struct wlr_renderer *renderer); -bool wlr_renderer_is_vk(const struct wlr_renderer *wlr_renderer); -bool wlr_texture_is_vk(const struct wlr_texture *texture); +bool wlr_renderer_is_vk(struct wlr_renderer *wlr_renderer); +bool wlr_texture_is_vk(struct wlr_texture *texture); void wlr_vk_texture_get_image_attribs(struct wlr_texture *texture, struct wlr_vk_image_attribs *attribs); diff --git a/include/wlr/types/wlr_cursor.h b/include/wlr/types/wlr_cursor.h index aaa18a437..041f735cf 100644 --- a/include/wlr/types/wlr_cursor.h +++ b/include/wlr/types/wlr_cursor.h @@ -49,30 +49,30 @@ struct wlr_cursor { * your responsibility. */ struct { - struct wl_signal motion; // struct wlr_pointer_motion_event - struct wl_signal motion_absolute; // struct wlr_pointer_motion_absolute_event - struct wl_signal button; // struct wlr_pointer_button_event - struct wl_signal axis; // struct wlr_pointer_axis_event + struct wl_signal motion; + struct wl_signal motion_absolute; + struct wl_signal button; + struct wl_signal axis; struct wl_signal frame; - struct wl_signal swipe_begin; // struct wlr_pointer_swipe_begin_event - struct wl_signal swipe_update; // struct wlr_pointer_swipe_update_event - struct wl_signal swipe_end; // struct wlr_pointer_swipe_end_event - struct wl_signal pinch_begin; // struct wlr_pointer_pinch_begin_event - struct wl_signal pinch_update; // struct wlr_pointer_pinch_update_event - struct wl_signal pinch_end; // struct wlr_pointer_pinch_end_event - struct wl_signal hold_begin; // struct wlr_pointer_hold_begin_event - struct wl_signal hold_end; // struct wlr_pointer_hold_end_event + struct wl_signal swipe_begin; + struct wl_signal swipe_update; + struct wl_signal swipe_end; + struct wl_signal pinch_begin; + struct wl_signal pinch_update; + struct wl_signal pinch_end; + struct wl_signal hold_begin; + struct wl_signal hold_end; - struct wl_signal touch_up; // struct wlr_touch_up_event - struct wl_signal touch_down; // struct wlr_touch_down_event - struct wl_signal touch_motion; // struct wlr_touch_motion_event - struct wl_signal touch_cancel; // struct wlr_touch_cancel_event + struct wl_signal touch_up; + struct wl_signal touch_down; + struct wl_signal touch_motion; + struct wl_signal touch_cancel; struct wl_signal touch_frame; - struct wl_signal tablet_tool_axis; // struct wlr_tablet_tool_axis_event - struct wl_signal tablet_tool_proximity; // struct wlr_tablet_tool_proximity_event - struct wl_signal tablet_tool_tip; // struct wlr_tablet_tool_tip_event - struct wl_signal tablet_tool_button; // struct wlr_tablet_tool_button_event + struct wl_signal tablet_tool_axis; + struct wl_signal tablet_tool_proximity; + struct wl_signal tablet_tool_tip; + struct wl_signal tablet_tool_button; } events; void *data; diff --git a/include/wlr/types/wlr_linux_drm_syncobj_v1.h b/include/wlr/types/wlr_linux_drm_syncobj_v1.h index 7fd55ec2e..733350412 100644 --- a/include/wlr/types/wlr_linux_drm_syncobj_v1.h +++ b/include/wlr/types/wlr_linux_drm_syncobj_v1.h @@ -19,12 +19,8 @@ struct wlr_linux_drm_syncobj_surface_v1_state { struct wlr_drm_syncobj_timeline *acquire_timeline; uint64_t acquire_point; - struct { - bool committed; - struct wlr_drm_syncobj_timeline *release_timeline; - uint64_t release_point; - struct wlr_drm_syncobj_merger *release_merger; - } WLR_PRIVATE; + struct wlr_drm_syncobj_timeline *release_timeline; + uint64_t release_point; }; struct wlr_linux_drm_syncobj_manager_v1 { @@ -59,19 +55,4 @@ struct wlr_linux_drm_syncobj_surface_v1_state *wlr_linux_drm_syncobj_v1_get_surf bool wlr_linux_drm_syncobj_v1_state_signal_release_with_buffer( struct wlr_linux_drm_syncobj_surface_v1_state *state, struct wlr_buffer *buffer); -/** - * Register a release point for buffer usage. - * - * This function may be called multiple times for the same commit. The client's - * release point will be signalled when all registered points are signalled, and - * a new buffer has been committed. - * - * Because the given release point may not be materialized, a wl_event_loop must - * be supplied to schedule a wait internally, if needed - */ -bool wlr_linux_drm_syncobj_v1_state_add_release_point( - struct wlr_linux_drm_syncobj_surface_v1_state *state, - struct wlr_drm_syncobj_timeline *release_timeline, uint64_t release_point, - struct wl_event_loop *event_loop); - #endif diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h index c8e44b0e6..4485b3694 100644 --- a/include/wlr/types/wlr_output.h +++ b/include/wlr/types/wlr_output.h @@ -77,7 +77,6 @@ enum wlr_output_state_field { WLR_OUTPUT_STATE_SIGNAL_TIMELINE = 1 << 11, WLR_OUTPUT_STATE_COLOR_TRANSFORM = 1 << 12, WLR_OUTPUT_STATE_IMAGE_DESCRIPTION = 1 << 13, - WLR_OUTPUT_STATE_COLOR_REPRESENTATION = 1 << 14, }; enum wlr_output_state_mode_type { @@ -143,10 +142,6 @@ struct wlr_output_state { * regular page-flip at the next wlr_output.frame event. */ bool tearing_page_flip; - // Set if (committed & WLR_OUTPUT_STATE_COLOR_REPRESENTATION) - enum wlr_color_encoding color_encoding; - enum wlr_color_range color_range; - enum wlr_output_state_mode_type mode_type; struct wlr_output_mode *mode; struct { @@ -210,8 +205,6 @@ struct wlr_output { enum wl_output_transform transform; enum wlr_output_adaptive_sync_status adaptive_sync_status; uint32_t render_format; - enum wlr_color_encoding color_encoding; - enum wlr_color_range color_range; const struct wlr_output_image_description *image_description; // Indicates whether making changes to adaptive sync status is supported. @@ -632,15 +625,6 @@ void wlr_output_state_set_color_transform(struct wlr_output_state *state, bool wlr_output_state_set_image_description(struct wlr_output_state *state, const struct wlr_output_image_description *image_desc); -/** - * Set the color encoding and range of the primary scanout buffer. - * - * Pass WLR_COLOR_ENCODING_NONE / WLR_COLOR_RANGE_NONE to reset to defaults. - */ -void wlr_output_state_set_color_encoding_and_range( - struct wlr_output_state *state, - enum wlr_color_encoding encoding, enum wlr_color_range range); - /** * Copies the output state from src to dst. It is safe to then * wlr_output_state_finish() src and have dst still be valid. diff --git a/include/wlr/types/wlr_scene.h b/include/wlr/types/wlr_scene.h index f6f97cfea..46635f4bf 100644 --- a/include/wlr/types/wlr_scene.h +++ b/include/wlr/types/wlr_scene.h @@ -131,6 +131,8 @@ struct wlr_scene_surface { struct wlr_addon addon; struct wl_listener outputs_update; + struct wl_listener output_enter; + struct wl_listener output_leave; struct wl_listener output_sample; struct wl_listener frame_done; struct wl_listener surface_destroy; @@ -153,8 +155,6 @@ struct wlr_scene_outputs_update_event { struct wlr_scene_output_sample_event { struct wlr_scene_output *output; bool direct_scanout; - struct wlr_drm_syncobj_timeline *release_timeline; - uint64_t release_point; }; struct wlr_scene_frame_done_event { @@ -171,6 +171,8 @@ struct wlr_scene_buffer { struct { struct wl_signal outputs_update; // struct wlr_scene_outputs_update_event + struct wl_signal output_enter; // struct wlr_scene_output + struct wl_signal output_leave; // struct wlr_scene_output struct wl_signal output_sample; // struct wlr_scene_output_sample_event struct wl_signal frame_done; // struct wlr_scene_frame_done_event } events; @@ -266,8 +268,6 @@ struct wlr_scene_output { struct wlr_drm_syncobj_timeline *in_timeline; uint64_t in_point; - struct wlr_drm_syncobj_timeline *out_timeline; - uint64_t out_point; } WLR_PRIVATE; }; diff --git a/include/wlr/types/wlr_switch.h b/include/wlr/types/wlr_switch.h index 2b9e91266..641df1991 100644 --- a/include/wlr/types/wlr_switch.h +++ b/include/wlr/types/wlr_switch.h @@ -36,7 +36,6 @@ struct wlr_switch { enum wlr_switch_type { WLR_SWITCH_TYPE_LID, WLR_SWITCH_TYPE_TABLET_MODE, - WLR_SWITCH_TYPE_KEYPAD_SLIDE, }; enum wlr_switch_state { diff --git a/include/wlr/types/wlr_virtual_keyboard_v1.h b/include/wlr/types/wlr_virtual_keyboard_v1.h index dda1530b1..babc535a5 100644 --- a/include/wlr/types/wlr_virtual_keyboard_v1.h +++ b/include/wlr/types/wlr_virtual_keyboard_v1.h @@ -33,27 +33,12 @@ struct wlr_virtual_keyboard_v1 { bool has_keymap; struct wl_list link; // wlr_virtual_keyboard_manager_v1.virtual_keyboards - - struct { - struct wl_listener seat_destroy; - } WLR_PRIVATE; }; struct wlr_virtual_keyboard_manager_v1* wlr_virtual_keyboard_manager_v1_create( struct wl_display *display); -/** - * Get the struct wlr_virtual_keyboard_v1 corresponding to a zwp_virtual_keyboard_v1 resource. - * - * Asserts that the resource is a valid zwp_virtual_keyboard_v1 resource created by wlroots. - * - * Returns NULL if the resource is inert. - */ -struct wlr_virtual_keyboard_v1 *wlr_virtual_keyboard_v1_from_resource( - struct wl_resource *resource); - struct wlr_virtual_keyboard_v1 *wlr_input_device_get_virtual_keyboard( struct wlr_input_device *wlr_dev); - #endif diff --git a/include/wlr/util/box.h b/include/wlr/util/box.h index f6809e0c3..64dcbc5cf 100644 --- a/include/wlr/util/box.h +++ b/include/wlr/util/box.h @@ -107,13 +107,6 @@ void wlr_fbox_transform(struct wlr_fbox *dest, const struct wlr_fbox *box, #ifdef WLR_USE_UNSTABLE -/** - * Checks whether two boxes intersect. - * - * Returns false if either box is empty. - */ -bool wlr_box_intersects(const struct wlr_box *a, const struct wlr_box *b); - /** * Returns true if the two boxes are equal, false otherwise. */ diff --git a/include/wlr/xcursor.h b/include/wlr/xcursor.h index 5e9c140ae..7cf333d70 100644 --- a/include/wlr/xcursor.h +++ b/include/wlr/xcursor.h @@ -47,7 +47,7 @@ /** * A still cursor image. * - * The buffer contains pixels laid out in a packed DRM_FORMAT_ARGB8888 format. + * The buffer contains pixels layed out in a packed DRM_FORMAT_ARGB8888 format. */ struct wlr_xcursor_image { uint32_t width; /* actual width */ diff --git a/include/xwayland/selection.h b/include/xwayland/selection.h index 2f333f8e0..308310232 100644 --- a/include/xwayland/selection.h +++ b/include/xwayland/selection.h @@ -82,9 +82,9 @@ void xwm_handle_selection_notify(struct wlr_xwm *xwm, xcb_selection_notify_event_t *event); int xwm_handle_xfixes_selection_notify(struct wlr_xwm *xwm, xcb_xfixes_selection_notify_event_t *event); -bool data_source_is_xwayland(const struct wlr_data_source *wlr_source); +bool data_source_is_xwayland(struct wlr_data_source *wlr_source); bool primary_selection_source_is_xwayland( - const struct wlr_primary_selection_source *wlr_source); + struct wlr_primary_selection_source *wlr_source); void xwm_seat_handle_start_drag(struct wlr_xwm *xwm, struct wlr_drag *drag); diff --git a/meson.build b/meson.build index 6d31bdc41..5b8f12073 100644 --- a/meson.build +++ b/meson.build @@ -1,7 +1,7 @@ project( 'wlroots', 'c', - version: '0.21.0-dev', + version: '0.20.0-rc1', license: 'MIT', meson_version: '>=1.3', default_options: [ @@ -178,10 +178,6 @@ if get_option('examples') subdir('tinywl') endif -if get_option('tests') - subdir('test') -endif - pkgconfig = import('pkgconfig') pkgconfig.generate( lib_wlr, diff --git a/meson.options b/meson.options index d8a8ca940..5863764aa 100644 --- a/meson.options +++ b/meson.options @@ -7,6 +7,5 @@ option('backends', type: 'array', choices: ['auto', 'drm', 'libinput', 'x11'], v option('allocators', type: 'array', choices: ['auto', 'gbm', 'udmabuf'], value: ['auto'], description: 'Select built-in allocators') option('session', type: 'feature', value: 'auto', description: 'Enable session support') -option('tests', type: 'boolean', value: true, description: 'Build tests and benchmarks') option('color-management', type: 'feature', value: 'auto', description: 'Enable support for color management') option('libliftoff', type: 'feature', value: 'auto', description: 'Enable support for libliftoff') diff --git a/protocol/wlr-export-dmabuf-unstable-v1.xml b/protocol/wlr-export-dmabuf-unstable-v1.xml index d41efbb1d..80ea012f5 100644 --- a/protocol/wlr-export-dmabuf-unstable-v1.xml +++ b/protocol/wlr-export-dmabuf-unstable-v1.xml @@ -192,7 +192,7 @@ - Unreferences the frame. This request must be called as soon as it's no + Unreferences the frame. This request must be called as soon as its no longer used. It can be called at any time by the client. The client will still have diff --git a/render/drm_syncobj.c b/render/drm_syncobj.c index 2abe2cff6..912a2b6e5 100644 --- a/render/drm_syncobj.c +++ b/render/drm_syncobj.c @@ -167,9 +167,10 @@ bool wlr_drm_syncobj_timeline_check(struct wlr_drm_syncobj_timeline *timeline, etime = ETIME; #endif - int ret = drmSyncobjTimelineWait(timeline->drm_fd, &timeline->handle, &point, 1, 0, flags, NULL); + uint32_t signaled_point; + int ret = drmSyncobjTimelineWait(timeline->drm_fd, &timeline->handle, &point, 1, 0, flags, &signaled_point); if (ret != 0 && ret != -etime) { - wlr_log_errno(WLR_ERROR, "drmSyncobjTimelineWait() failed"); + wlr_log_errno(WLR_ERROR, "drmSyncobjWait() failed"); return false; } @@ -177,14 +178,6 @@ bool wlr_drm_syncobj_timeline_check(struct wlr_drm_syncobj_timeline *timeline, return true; } -bool wlr_drm_syncobj_timeline_signal(struct wlr_drm_syncobj_timeline *timeline, uint64_t point) { - if (drmSyncobjTimelineSignal(timeline->drm_fd, &timeline->handle, &point, 1) != 0) { - wlr_log(WLR_ERROR, "drmSyncobjTimelineSignal() failed"); - return false; - } - return true; -} - static int handle_eventfd_ready(int ev_fd, uint32_t mask, void *data) { struct wlr_drm_syncobj_timeline_waiter *waiter = data; diff --git a/render/drm_syncobj_merger.c b/render/drm_syncobj_merger.c deleted file mode 100644 index d50d28c28..000000000 --- a/render/drm_syncobj_merger.c +++ /dev/null @@ -1,133 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include "render/drm_syncobj_merger.h" - -#include "config.h" - -#if HAVE_LINUX_SYNC_FILE - -#include -#include - -static int sync_file_merge(int fd1, int fd2) { - // The kernel will automatically prune signalled fences - struct sync_merge_data merge_data = { .fd2 = fd2 }; - if (ioctl(fd1, SYNC_IOC_MERGE, &merge_data) < 0) { - wlr_log_errno(WLR_ERROR, "ioctl(SYNC_IOC_MERGE) failed"); - return -1; - } - - return merge_data.fence; -} - -#else - -static int sync_file_merge(int fd1, int fd2) { - wlr_log(WLR_ERROR, "sync_file support is unavailable"); - return -1; -} - -#endif - -struct wlr_drm_syncobj_merger *wlr_drm_syncobj_merger_create( - struct wlr_drm_syncobj_timeline *dst_timeline, uint64_t dst_point) { - struct wlr_drm_syncobj_merger *merger = calloc(1, sizeof(*merger)); - if (merger == NULL) { - return NULL; - } - merger->n_ref = 1; - merger->dst_timeline = wlr_drm_syncobj_timeline_ref(dst_timeline); - merger->dst_point = dst_point; - merger->sync_fd = -1; - return merger; -} - -struct wlr_drm_syncobj_merger *wlr_drm_syncobj_merger_ref( - struct wlr_drm_syncobj_merger *merger) { - assert(merger->n_ref > 0); - merger->n_ref++; - return merger; -} - -void wlr_drm_syncobj_merger_unref(struct wlr_drm_syncobj_merger *merger) { - if (merger == NULL) { - return; - } - assert(merger->n_ref > 0); - merger->n_ref--; - if (merger->n_ref > 0) { - return; - } - - if (merger->sync_fd != -1) { - wlr_drm_syncobj_timeline_import_sync_file(merger->dst_timeline, - merger->dst_point, merger->sync_fd); - close(merger->sync_fd); - } else { - wlr_drm_syncobj_timeline_signal(merger->dst_timeline, merger->dst_point); - } - wlr_drm_syncobj_timeline_unref(merger->dst_timeline); - free(merger); -} - -static bool merger_add_exportable(struct wlr_drm_syncobj_merger *merger, - struct wlr_drm_syncobj_timeline *src_timeline, uint64_t src_point) { - int new_sync = wlr_drm_syncobj_timeline_export_sync_file(src_timeline, src_point); - if (merger->sync_fd != -1) { - int fd2 = new_sync; - new_sync = sync_file_merge(merger->sync_fd, fd2); - close(fd2); - close(merger->sync_fd); - } - merger->sync_fd = new_sync; - return true; -} - -struct export_waiter { - struct wlr_drm_syncobj_timeline_waiter waiter; - struct wlr_drm_syncobj_merger *merger; - struct wlr_drm_syncobj_timeline *src_timeline; - uint64_t src_point; -}; - -static void export_waiter_handle_ready(struct wlr_drm_syncobj_timeline_waiter *waiter) { - struct export_waiter *add = wl_container_of(waiter, add, waiter); - merger_add_exportable(add->merger, add->src_timeline, add->src_point); - wlr_drm_syncobj_merger_unref(add->merger); - wlr_drm_syncobj_timeline_unref(add->src_timeline); - wlr_drm_syncobj_timeline_waiter_finish(&add->waiter); - free(add); -} - -bool wlr_drm_syncobj_merger_add(struct wlr_drm_syncobj_merger *merger, - struct wlr_drm_syncobj_timeline *src_timeline, uint64_t src_point, - struct wl_event_loop *loop) { - assert(loop != NULL); - bool exportable = false; - int flags = DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE; - if (!wlr_drm_syncobj_timeline_check(src_timeline, src_point, flags, &exportable)) { - return false; - } - if (exportable) { - return merger_add_exportable(merger, src_timeline, src_point); - } - struct export_waiter *add = calloc(1, sizeof(*add)); - if (add == NULL) { - return false; - } - if (!wlr_drm_syncobj_timeline_waiter_init(&add->waiter, src_timeline, src_point, - flags, loop, export_waiter_handle_ready)) { - return false; - } - add->merger = merger; - add->src_timeline = wlr_drm_syncobj_timeline_ref(src_timeline); - add->src_point = src_point; - merger->n_ref++; - return true; -} diff --git a/render/egl.c b/render/egl.c index 8673acabf..6f3e9c8ca 100644 --- a/render/egl.c +++ b/render/egl.c @@ -156,7 +156,7 @@ static void init_dmabuf_formats(struct wlr_egl *egl) { } if (modifiers_len == 0) { - // Assume the linear layout is supported if the driver doesn't + // Asume the linear layout is supported if the driver doesn't // explicitly say otherwise wlr_drm_format_set_add(&egl->dmabuf_texture_formats, fmt, DRM_FORMAT_MOD_LINEAR); diff --git a/render/gles2/pass.c b/render/gles2/pass.c index a70ea1320..b10ac047d 100644 --- a/render/gles2/pass.c +++ b/render/gles2/pass.c @@ -260,26 +260,17 @@ static void render_pass_add_rect(struct wlr_render_pass *wlr_pass, const struct wlr_render_color *color = &options->color; struct wlr_box box; - struct wlr_buffer *wlr_buffer = pass->buffer->buffer; - wlr_render_rect_options_get_box(options, wlr_buffer, &box); + wlr_render_rect_options_get_box(options, pass->buffer->buffer, &box); push_gles2_debug(renderer); - enum wlr_render_blend_mode blend_mode = - color->a == 1.0 ? WLR_RENDER_BLEND_MODE_NONE : options->blend_mode; - if (blend_mode == WLR_RENDER_BLEND_MODE_NONE && - options->clip == NULL && - box.x == 0 && box.y == 0 && - box.width == wlr_buffer->width && - box.height == wlr_buffer->height) { - glClearColor(color->r, color->g, color->b, color->a); - glClear(GL_COLOR_BUFFER_BIT); - } else { - setup_blending(blend_mode); - glUseProgram(renderer->shaders.quad.program); - set_proj_matrix(renderer->shaders.quad.proj, pass->projection_matrix, &box); - glUniform4f(renderer->shaders.quad.color, color->r, color->g, color->b, color->a); - render(&box, options->clip, renderer->shaders.quad.pos_attrib); - } + setup_blending(color->a == 1.0 ? WLR_RENDER_BLEND_MODE_NONE : options->blend_mode); + + glUseProgram(renderer->shaders.quad.program); + + set_proj_matrix(renderer->shaders.quad.proj, pass->projection_matrix, &box); + glUniform4f(renderer->shaders.quad.color, color->r, color->g, color->b, color->a); + + render(&box, options->clip, renderer->shaders.quad.pos_attrib); pop_gles2_debug(renderer); } diff --git a/render/gles2/renderer.c b/render/gles2/renderer.c index 7f01b8acd..e362daee8 100644 --- a/render/gles2/renderer.c +++ b/render/gles2/renderer.c @@ -29,7 +29,7 @@ static const struct wlr_renderer_impl renderer_impl; static const struct wlr_render_timer_impl render_timer_impl; -bool wlr_renderer_is_gles2(const struct wlr_renderer *wlr_renderer) { +bool wlr_renderer_is_gles2(struct wlr_renderer *wlr_renderer) { return wlr_renderer->impl == &renderer_impl; } @@ -40,7 +40,7 @@ struct wlr_gles2_renderer *gles2_get_renderer( return renderer; } -bool wlr_render_timer_is_gles2(const struct wlr_render_timer *timer) { +bool wlr_render_timer_is_gles2(struct wlr_render_timer *timer) { return timer->impl == &render_timer_impl; } diff --git a/render/gles2/texture.c b/render/gles2/texture.c index 7460755cd..9a967ebdb 100644 --- a/render/gles2/texture.c +++ b/render/gles2/texture.c @@ -16,7 +16,7 @@ static const struct wlr_texture_impl texture_impl; -bool wlr_texture_is_gles2(const struct wlr_texture *wlr_texture) { +bool wlr_texture_is_gles2(struct wlr_texture *wlr_texture) { return wlr_texture->impl == &texture_impl; } diff --git a/render/meson.build b/render/meson.build index 517d76bf0..aaaf2ec48 100644 --- a/render/meson.build +++ b/render/meson.build @@ -9,7 +9,6 @@ wlr_files += files( 'color.c', 'dmabuf.c', 'drm_format_set.c', - 'drm_syncobj_merger.c', 'drm_syncobj.c', 'pass.c', 'pixel_format.c', @@ -29,7 +28,6 @@ else endif internal_config.set10('HAVE_EVENTFD', cc.has_header('sys/eventfd.h')) -internal_config.set10('HAVE_LINUX_SYNC_FILE', cc.has_header('linux/sync_file.h')) if 'gles2' in renderers or 'auto' in renderers egl = dependency('egl', required: 'gles2' in renderers) diff --git a/render/pixel_format.c b/render/pixel_format.c index c60dd9d2a..5f2e8644a 100644 --- a/render/pixel_format.c +++ b/render/pixel_format.c @@ -307,68 +307,3 @@ bool pixel_format_has_alpha(uint32_t fmt) { } return true; } - -bool pixel_format_is_ycbcr(uint32_t format) { - switch (format) { - case DRM_FORMAT_AYUV: - case DRM_FORMAT_NV12: - case DRM_FORMAT_NV15: - case DRM_FORMAT_NV16: - case DRM_FORMAT_NV20: - case DRM_FORMAT_NV21: - case DRM_FORMAT_NV24: - case DRM_FORMAT_NV30: - case DRM_FORMAT_NV42: - case DRM_FORMAT_NV61: - case DRM_FORMAT_P010: - case DRM_FORMAT_P012: - case DRM_FORMAT_P016: - case DRM_FORMAT_P030: - case DRM_FORMAT_P210: - case DRM_FORMAT_Q401: - case DRM_FORMAT_Q410: - case DRM_FORMAT_S010: - case DRM_FORMAT_S012: - case DRM_FORMAT_S016: - case DRM_FORMAT_S210: - case DRM_FORMAT_S212: - case DRM_FORMAT_S216: - case DRM_FORMAT_S410: - case DRM_FORMAT_S412: - case DRM_FORMAT_S416: - case DRM_FORMAT_UYVY: - case DRM_FORMAT_VUY101010: - case DRM_FORMAT_VUY888: - case DRM_FORMAT_VYUY: - case DRM_FORMAT_X0L0: - case DRM_FORMAT_X0L2: - case DRM_FORMAT_XVYU12_16161616: - case DRM_FORMAT_XVYU16161616: - case DRM_FORMAT_XVYU2101010: - case DRM_FORMAT_XYUV8888: - case DRM_FORMAT_Y0L0: - case DRM_FORMAT_Y0L2: - case DRM_FORMAT_Y210: - case DRM_FORMAT_Y212: - case DRM_FORMAT_Y216: - case DRM_FORMAT_Y410: - case DRM_FORMAT_Y412: - case DRM_FORMAT_Y416: - case DRM_FORMAT_YUV410: - case DRM_FORMAT_YUV411: - case DRM_FORMAT_YUV420: - case DRM_FORMAT_YUV420_10BIT: - case DRM_FORMAT_YUV420_8BIT: - case DRM_FORMAT_YUV422: - case DRM_FORMAT_YUV444: - case DRM_FORMAT_YUYV: - case DRM_FORMAT_YVU410: - case DRM_FORMAT_YVU411: - case DRM_FORMAT_YVU420: - case DRM_FORMAT_YVU422: - case DRM_FORMAT_YVU444: - case DRM_FORMAT_YVYU: - return true; - } - return false; -} diff --git a/render/pixman/pass.c b/render/pixman/pass.c index d3ee17dca..4ae742cab 100644 --- a/render/pixman/pass.c +++ b/render/pixman/pass.c @@ -78,7 +78,7 @@ static void render_pass_add_texture(struct wlr_render_pass *wlr_pass, if (options->transform != WL_OUTPUT_TRANSFORM_NORMAL || src_box_transformed.width != dst_box.width || src_box_transformed.height != dst_box.height) { - // Cosinus/sinus values are exact integers for enum wl_output_transform entries + // Cosinus/sinus values are extact integers for enum wl_output_transform entries int tr_cos = 1, tr_sin = 0, tr_x = 0, tr_y = 0; switch (options->transform) { case WL_OUTPUT_TRANSFORM_NORMAL: diff --git a/render/pixman/renderer.c b/render/pixman/renderer.c index 25c558a9d..4631a33ab 100644 --- a/render/pixman/renderer.c +++ b/render/pixman/renderer.c @@ -12,7 +12,7 @@ static const struct wlr_renderer_impl renderer_impl; -bool wlr_renderer_is_pixman(const struct wlr_renderer *wlr_renderer) { +bool wlr_renderer_is_pixman(struct wlr_renderer *wlr_renderer) { return wlr_renderer->impl == &renderer_impl; } @@ -69,7 +69,7 @@ static struct wlr_pixman_buffer *get_buffer( static const struct wlr_texture_impl texture_impl; -bool wlr_texture_is_pixman(const struct wlr_texture *texture) { +bool wlr_texture_is_pixman(struct wlr_texture *texture) { return texture->impl == &texture_impl; } diff --git a/render/vulkan/pass.c b/render/vulkan/pass.c index 503e37c07..31f5116bd 100644 --- a/render/vulkan/pass.c +++ b/render/vulkan/pass.c @@ -146,40 +146,6 @@ static VkSemaphore render_pass_wait_sync_file(struct wlr_vk_render_pass *pass, return *sem_ptr; } -static bool render_pass_wait_render_buffer(struct wlr_vk_render_pass *pass, - VkSemaphoreSubmitInfoKHR *render_wait, uint32_t *render_wait_len_ptr) { - int sync_file_fds[WLR_DMABUF_MAX_PLANES]; - for (size_t i = 0; i < WLR_DMABUF_MAX_PLANES; i++) { - sync_file_fds[i] = -1; - } - - if (!vulkan_sync_render_buffer_acquire(pass->render_buffer, sync_file_fds)) { - return false; - } - - for (size_t i = 0; i < WLR_DMABUF_MAX_PLANES; i++) { - if (sync_file_fds[i] < 0) { - continue; - } - - VkSemaphore sem = render_pass_wait_sync_file(pass, *render_wait_len_ptr, sync_file_fds[i]); - if (sem == VK_NULL_HANDLE) { - close(sync_file_fds[i]); - continue; - } - - render_wait[*render_wait_len_ptr] = (VkSemaphoreSubmitInfoKHR){ - .sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO_KHR, - .semaphore = sem, - .stageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR, - }; - - (*render_wait_len_ptr)++; - } - - return true; -} - static bool unwrap_color_transform(struct wlr_color_transform *transform, float matrix[static 9], enum wlr_color_transfer_function *tf) { if (transform == NULL) { @@ -342,7 +308,7 @@ static bool render_pass_submit(struct wlr_render_pass *wlr_pass) { vkCmdEndRenderPass(render_cb->vk); size_t pass_textures_len = pass->textures.size / sizeof(struct wlr_vk_render_pass_texture); - size_t render_wait_cap = (1 + pass_textures_len) * WLR_DMABUF_MAX_PLANES; + size_t render_wait_cap = pass_textures_len * WLR_DMABUF_MAX_PLANES; render_wait = calloc(render_wait_cap, sizeof(*render_wait)); if (render_wait == NULL) { wlr_log_errno(WLR_ERROR, "Allocation failed"); @@ -420,7 +386,7 @@ static bool render_pass_submit(struct wlr_render_pass *wlr_pass) { sync_file_fds[0] = sync_file_fd; } else { struct wlr_vk_texture *texture = pass_texture->texture; - if (!vulkan_sync_foreign_texture_acquire(texture, sync_file_fds)) { + if (!vulkan_sync_foreign_texture(texture, sync_file_fds)) { wlr_log(WLR_ERROR, "Failed to wait for foreign texture DMA-BUF fence"); continue; } @@ -447,10 +413,6 @@ static bool render_pass_submit(struct wlr_render_pass *wlr_pass) { } } - if (!render_pass_wait_render_buffer(pass, render_wait, &render_wait_len)) { - wlr_log(WLR_ERROR, "Failed to wait for render buffer DMA-BUF fence"); - } - // also add acquire/release barriers for the current render buffer VkImageLayout src_layout = VK_IMAGE_LAYOUT_GENERAL; if (!pass->render_buffer_out->transitioned) { @@ -644,7 +606,8 @@ static bool render_pass_submit(struct wlr_render_pass *wlr_pass) { wl_list_insert(&stage_cb->stage_buffers, &stage_buf->link); } - if (!vulkan_sync_render_pass_release(renderer, pass)) { + if (!vulkan_sync_render_buffer(renderer, render_buffer, render_cb, + pass->signal_timeline, pass->signal_point)) { wlr_log(WLR_ERROR, "Failed to sync render buffer"); } @@ -859,13 +822,12 @@ static void render_pass_add_texture(struct wlr_render_pass *wlr_pass, } enum wlr_color_encoding color_encoding = options->color_encoding; - bool is_ycbcr = vulkan_format_is_ycbcr(texture->format); - if (is_ycbcr && color_encoding == WLR_COLOR_ENCODING_NONE) { + if (texture->format->is_ycbcr && color_encoding == WLR_COLOR_ENCODING_NONE) { color_encoding = WLR_COLOR_ENCODING_BT601; } enum wlr_color_range color_range = options->color_range; - if (is_ycbcr && color_range == WLR_COLOR_RANGE_NONE) { + if (texture->format->is_ycbcr && color_range == WLR_COLOR_RANGE_NONE) { color_range = WLR_COLOR_RANGE_LIMITED; } @@ -875,7 +837,7 @@ static void render_pass_add_texture(struct wlr_render_pass *wlr_pass, .source = WLR_VK_SHADER_SOURCE_TEXTURE, .layout = { .ycbcr = { - .format = is_ycbcr ? texture->format : NULL, + .format = texture->format->is_ycbcr ? texture->format : NULL, .encoding = color_encoding, .range = color_range, }, diff --git a/render/vulkan/pixel_format.c b/render/vulkan/pixel_format.c index 9b17d079a..902feac9a 100644 --- a/render/vulkan/pixel_format.c +++ b/render/vulkan/pixel_format.c @@ -182,30 +182,37 @@ static const struct wlr_vk_format formats[] = { { .drm = DRM_FORMAT_UYVY, .vk = VK_FORMAT_B8G8R8G8_422_UNORM, + .is_ycbcr = true, }, { .drm = DRM_FORMAT_YUYV, .vk = VK_FORMAT_G8B8G8R8_422_UNORM, + .is_ycbcr = true, }, { .drm = DRM_FORMAT_NV12, .vk = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, + .is_ycbcr = true, }, { .drm = DRM_FORMAT_NV16, .vk = VK_FORMAT_G8_B8R8_2PLANE_422_UNORM, + .is_ycbcr = true, }, { .drm = DRM_FORMAT_YUV420, .vk = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM, + .is_ycbcr = true, }, { .drm = DRM_FORMAT_YUV422, .vk = VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM, + .is_ycbcr = true, }, { .drm = DRM_FORMAT_YUV444, .vk = VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM, + .is_ycbcr = true, }, // 3PACK16 formats split the memory in three 16-bit words, so they have an // inverted channel order compared to DRM formats. @@ -213,22 +220,27 @@ static const struct wlr_vk_format formats[] = { { .drm = DRM_FORMAT_P010, .vk = VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16, + .is_ycbcr = true, }, { .drm = DRM_FORMAT_P210, .vk = VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16, + .is_ycbcr = true, }, { .drm = DRM_FORMAT_P012, .vk = VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16, + .is_ycbcr = true, }, { .drm = DRM_FORMAT_P016, .vk = VK_FORMAT_G16_B16R16_2PLANE_420_UNORM, + .is_ycbcr = true, }, { .drm = DRM_FORMAT_Q410, .vk = VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16, + .is_ycbcr = true, }, #endif // TODO: add DRM_FORMAT_NV24/VK_FORMAT_G8_B8R8_2PLANE_444_UNORM (requires @@ -434,7 +446,7 @@ static bool query_modifier_support(struct wlr_vk_device *dev, // check that specific modifier for render usage const char *errmsg = "unknown error"; if ((m.drmFormatModifierTilingFeatures & render_features) == render_features && - !vulkan_format_is_ycbcr(&props->format)) { + !props->format.is_ycbcr) { struct wlr_vk_format_modifier_props p = {0}; bool supported = false; if (query_modifier_usage_support(dev, props->format.vk, @@ -465,7 +477,7 @@ static bool query_modifier_support(struct wlr_vk_device *dev, // check that specific modifier for texture usage errmsg = "unknown error"; VkFormatFeatureFlags features = dma_tex_features; - if (vulkan_format_is_ycbcr(&props->format)) { + if (props->format.is_ycbcr) { features |= ycbcr_tex_features; } if ((m.drmFormatModifierTilingFeatures & features) == features) { @@ -510,7 +522,7 @@ static bool query_modifier_support(struct wlr_vk_device *dev, void vulkan_format_props_query(struct wlr_vk_device *dev, const struct wlr_vk_format *format) { - if (vulkan_format_is_ycbcr(format) && !dev->sampler_ycbcr_conversion) { + if (format->is_ycbcr && !dev->sampler_ycbcr_conversion) { return; } @@ -539,7 +551,7 @@ void vulkan_format_props_query(struct wlr_vk_device *dev, char shm_texture_status[256]; const char *errmsg = "unknown error"; if ((fmtp.formatProperties.optimalTilingFeatures & shm_tex_features) == shm_tex_features && - !vulkan_format_is_ycbcr(format) && format_info != NULL) { + !format->is_ycbcr && format_info != NULL) { VkImageFormatProperties ifmtp; bool supported = false, has_mutable_srgb = false; if (query_shm_support(dev, format->vk, format->vk_srgb, &ifmtp, &errmsg)) { @@ -609,7 +621,3 @@ const struct wlr_vk_format_modifier_props *vulkan_format_props_find_modifier( } return NULL; } - -bool vulkan_format_is_ycbcr(const struct wlr_vk_format *format) { - return pixel_format_is_ycbcr(format->drm); -} diff --git a/render/vulkan/renderer.c b/render/vulkan/renderer.c index 52c87e9e2..0b411f5dd 100644 --- a/render/vulkan/renderer.c +++ b/render/vulkan/renderer.c @@ -46,7 +46,7 @@ static bool default_debug = true; static const struct wlr_renderer_impl renderer_impl; -bool wlr_renderer_is_vk(const struct wlr_renderer *wlr_renderer) { +bool wlr_renderer_is_vk(struct wlr_renderer *wlr_renderer) { return wlr_renderer->impl == &renderer_impl; } @@ -968,11 +968,13 @@ static struct wlr_vk_render_buffer *get_render_buffer( return buffer; } -static bool buffer_export_sync_file(struct wlr_vk_renderer *renderer, struct wlr_buffer *buffer, - uint32_t flags, int sync_file_fds[static WLR_DMABUF_MAX_PLANES]) { +bool vulkan_sync_foreign_texture(struct wlr_vk_texture *texture, + int sync_file_fds[static WLR_DMABUF_MAX_PLANES]) { + struct wlr_vk_renderer *renderer = texture->renderer; + struct wlr_dmabuf_attributes dmabuf = {0}; - if (!wlr_buffer_get_dmabuf(buffer, &dmabuf)) { - wlr_log(WLR_ERROR, "wlr_buffer_get_dmabuf() failed"); + if (!wlr_buffer_get_dmabuf(texture->buffer, &dmabuf)) { + wlr_log(WLR_ERROR, "Failed to get texture DMA-BUF"); return false; } @@ -982,7 +984,7 @@ static bool buffer_export_sync_file(struct wlr_vk_renderer *renderer, struct wlr for (int i = 0; i < dmabuf.n_planes; i++) { struct pollfd pollfd = { .fd = dmabuf.fd[i], - .events = (flags & DMA_BUF_SYNC_WRITE) ? POLLOUT : POLLIN, + .events = POLLIN, }; int timeout_ms = 1000; int ret = poll(&pollfd, 1, timeout_ms); @@ -999,7 +1001,7 @@ static bool buffer_export_sync_file(struct wlr_vk_renderer *renderer, struct wlr } for (int i = 0; i < dmabuf.n_planes; i++) { - int sync_file_fd = dmabuf_export_sync_file(dmabuf.fd[i], flags); + int sync_file_fd = dmabuf_export_sync_file(dmabuf.fd[i], DMA_BUF_SYNC_READ); if (sync_file_fd < 0) { wlr_log(WLR_ERROR, "Failed to extract DMA-BUF fence"); return false; @@ -1011,40 +1013,12 @@ static bool buffer_export_sync_file(struct wlr_vk_renderer *renderer, struct wlr return true; } -bool vulkan_sync_foreign_texture_acquire(struct wlr_vk_texture *texture, - int sync_file_fds[static WLR_DMABUF_MAX_PLANES]) { - return buffer_export_sync_file(texture->renderer, texture->buffer, DMA_BUF_SYNC_READ, sync_file_fds); -} - -bool vulkan_sync_render_buffer_acquire(struct wlr_vk_render_buffer *render_buffer, - int sync_file_fds[static WLR_DMABUF_MAX_PLANES]) { - return buffer_export_sync_file(render_buffer->renderer, render_buffer->wlr_buffer, - DMA_BUF_SYNC_WRITE, sync_file_fds); -} - -static bool buffer_import_sync_file(struct wlr_buffer *buffer, uint32_t flags, int sync_file_fd) { - struct wlr_dmabuf_attributes dmabuf = {0}; - if (!wlr_buffer_get_dmabuf(buffer, &dmabuf)) { - wlr_log(WLR_ERROR, "wlr_buffer_get_dmabuf() failed"); - return false; - } - - for (int i = 0; i < dmabuf.n_planes; i++) { - if (!dmabuf_import_sync_file(dmabuf.fd[i], flags, - sync_file_fd)) { - return false; - } - } - - return true; -} - -bool vulkan_sync_render_pass_release(struct wlr_vk_renderer *renderer, - struct wlr_vk_render_pass *pass) { +bool vulkan_sync_render_buffer(struct wlr_vk_renderer *renderer, + struct wlr_vk_render_buffer *render_buffer, struct wlr_vk_command_buffer *cb, + struct wlr_drm_syncobj_timeline *signal_timeline, uint64_t signal_point) { VkResult res; - struct wlr_vk_command_buffer *cb = pass->command_buffer; - if (!renderer->dev->implicit_sync_interop && pass->signal_timeline == NULL) { + if (!renderer->dev->implicit_sync_interop && signal_timeline == NULL) { // We have no choice but to block here sadly return vulkan_wait_command_buffer(cb, renderer); } @@ -1066,19 +1040,21 @@ bool vulkan_sync_render_pass_release(struct wlr_vk_renderer *renderer, } bool ok = false; - if (pass->signal_timeline != NULL) { - if (!wlr_drm_syncobj_timeline_import_sync_file(pass->signal_timeline, - pass->signal_point, sync_file_fd)) { + if (signal_timeline != NULL) { + if (!wlr_drm_syncobj_timeline_import_sync_file(signal_timeline, + signal_point, sync_file_fd)) { goto out; } } else { - if (!buffer_import_sync_file(pass->render_buffer->wlr_buffer, DMA_BUF_SYNC_WRITE, sync_file_fd)) { + struct wlr_dmabuf_attributes dmabuf = {0}; + if (!wlr_buffer_get_dmabuf(render_buffer->wlr_buffer, &dmabuf)) { + wlr_log(WLR_ERROR, "wlr_buffer_get_dmabuf failed"); goto out; } - struct wlr_vk_render_pass_texture *pass_texture; - wl_array_for_each(pass_texture, &pass->textures) { - if (!buffer_import_sync_file(pass_texture->texture->buffer, DMA_BUF_SYNC_READ, sync_file_fd)) { + for (int i = 0; i < dmabuf.n_planes; i++) { + if (!dmabuf_import_sync_file(dmabuf.fd[i], DMA_BUF_SYNC_WRITE, + sync_file_fd)) { goto out; } } @@ -1188,7 +1164,7 @@ static void vulkan_destroy(struct wlr_renderer *wlr_renderer) { vkDestroyPipelineLayout(dev->dev, pipeline_layout->vk, NULL); vkDestroyDescriptorSetLayout(dev->dev, pipeline_layout->ds, NULL); vkDestroySampler(dev->dev, pipeline_layout->sampler, NULL); - renderer->dev->api.vkDestroySamplerYcbcrConversionKHR(dev->dev, pipeline_layout->ycbcr.conversion, NULL); + vkDestroySamplerYcbcrConversion(dev->dev, pipeline_layout->ycbcr.conversion, NULL); free(pipeline_layout); } @@ -1654,8 +1630,8 @@ static bool init_blend_to_output_layouts(struct wlr_vk_renderer *renderer) { static bool pipeline_layout_key_equals( const struct wlr_vk_pipeline_layout_key *a, const struct wlr_vk_pipeline_layout_key *b) { - assert(!a->ycbcr.format || vulkan_format_is_ycbcr(a->ycbcr.format)); - assert(!b->ycbcr.format || vulkan_format_is_ycbcr(b->ycbcr.format)); + assert(!a->ycbcr.format || a->ycbcr.format->is_ycbcr); + assert(!b->ycbcr.format || b->ycbcr.format->is_ycbcr); if (a->filter_mode != b->filter_mode) { return false; @@ -2049,10 +2025,10 @@ struct wlr_vk_pipeline_layout *get_or_create_pipeline_layout( .yChromaOffset = VK_CHROMA_LOCATION_MIDPOINT, .chromaFilter = VK_FILTER_LINEAR, }; - res = renderer->dev->api.vkCreateSamplerYcbcrConversionKHR(renderer->dev->dev, + res = vkCreateSamplerYcbcrConversion(renderer->dev->dev, &conversion_create_info, NULL, &pipeline_layout->ycbcr.conversion); if (res != VK_SUCCESS) { - wlr_vk_error("vkCreateSamplerYcbcrConversionKHR", res); + wlr_vk_error("vkCreateSamplerYcbcrConversion", res); free(pipeline_layout); return NULL; } @@ -2063,8 +2039,8 @@ struct wlr_vk_pipeline_layout *get_or_create_pipeline_layout( }; sampler_create_info.pNext = &conversion_info; } else { - assert(key->ycbcr.encoding == WLR_COLOR_ENCODING_NONE || key->ycbcr.encoding == WLR_COLOR_ENCODING_IDENTITY); - assert(key->ycbcr.range == WLR_COLOR_RANGE_NONE || key->ycbcr.range == WLR_COLOR_RANGE_FULL); + assert(key->ycbcr.encoding == WLR_COLOR_ENCODING_NONE); + assert(key->ycbcr.range == WLR_COLOR_RANGE_NONE); } res = vkCreateSampler(renderer->dev->dev, &sampler_create_info, NULL, &pipeline_layout->sampler); diff --git a/render/vulkan/shaders/common.vert b/render/vulkan/shaders/common.vert index f1579790d..c6175d248 100644 --- a/render/vulkan/shaders/common.vert +++ b/render/vulkan/shaders/common.vert @@ -1,7 +1,7 @@ #version 450 // we use a mat4 since it uses the same size as mat3 due to -// alignment. Easier to deal with (tightly-packed) mat4 though. +// alignment. Easier to deal with (tighly-packed) mat4 though. layout(push_constant, row_major) uniform UBO { mat4 proj; vec2 uv_offset; diff --git a/render/vulkan/texture.c b/render/vulkan/texture.c index d769a0b9e..499178f5d 100644 --- a/render/vulkan/texture.c +++ b/render/vulkan/texture.c @@ -15,7 +15,7 @@ static const struct wlr_texture_impl texture_impl; -bool wlr_texture_is_vk(const struct wlr_texture *wlr_texture) { +bool wlr_texture_is_vk(struct wlr_texture *wlr_texture) { return wlr_texture->impl == &texture_impl; } @@ -189,7 +189,7 @@ void vulkan_texture_destroy(struct wlr_vk_texture *texture) { // when we recorded a command to fill this image _this_ frame, // it has to be executed before the texture can be destroyed. // Add it to the renderer->destroy_textures list, destroying - // _after_ the stage command buffer has executed + // _after_ the stage command buffer has exectued if (texture->last_used_cb != NULL) { assert(texture->destroy_link.next == NULL); // not already inserted wl_list_insert(&texture->last_used_cb->destroy_textures, @@ -297,7 +297,7 @@ struct wlr_vk_texture_view *vulkan_texture_get_or_create_view(struct wlr_vk_text .components.r = VK_COMPONENT_SWIZZLE_IDENTITY, .components.g = VK_COMPONENT_SWIZZLE_IDENTITY, .components.b = VK_COMPONENT_SWIZZLE_IDENTITY, - .components.a = texture->has_alpha || vulkan_format_is_ycbcr(texture->format) + .components.a = texture->has_alpha || texture->format->is_ycbcr ? VK_COMPONENT_SWIZZLE_IDENTITY : VK_COMPONENT_SWIZZLE_ONE, .subresourceRange = (VkImageSubresourceRange){ @@ -311,7 +311,7 @@ struct wlr_vk_texture_view *vulkan_texture_get_or_create_view(struct wlr_vk_text }; VkSamplerYcbcrConversionInfo ycbcr_conversion_info; - if (vulkan_format_is_ycbcr(texture->format)) { + if (texture->format->is_ycbcr) { assert(pipeline_layout->ycbcr.conversion != VK_NULL_HANDLE); ycbcr_conversion_info = (VkSamplerYcbcrConversionInfo){ .sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO, @@ -355,7 +355,7 @@ struct wlr_vk_texture_view *vulkan_texture_get_or_create_view(struct wlr_vk_text static void texture_set_format(struct wlr_vk_texture *texture, const struct wlr_vk_format *format, bool has_mutable_srgb) { - assert(!(vulkan_format_is_ycbcr(format) && has_mutable_srgb)); + assert(!(format->is_ycbcr && has_mutable_srgb)); texture->format = format; texture->using_mutable_srgb = has_mutable_srgb; @@ -366,7 +366,7 @@ static void texture_set_format(struct wlr_vk_texture *texture, texture->has_alpha = pixel_format_has_alpha(format->drm); } else { // We don't have format info for multi-planar formats - assert(vulkan_format_is_ycbcr(texture->format)); + assert(texture->format->is_ycbcr); } } @@ -378,7 +378,7 @@ static struct wlr_texture *vulkan_texture_from_pixels( const struct wlr_vk_format_props *fmt = vulkan_format_props_from_drm(renderer->dev, drm_fmt); - if (fmt == NULL || vulkan_format_is_ycbcr(&fmt->format)) { + if (fmt == NULL || fmt->format.is_ycbcr) { char *format_name = drmGetFormatName(drm_fmt); wlr_log(WLR_ERROR, "Unsupported pixel format %s (0x%08"PRIX32")", format_name, drm_fmt); @@ -653,7 +653,7 @@ VkImage vulkan_import_dmabuf(struct wlr_vk_renderer *renderer, .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, }; - renderer->dev->api.vkGetImageMemoryRequirements2KHR(dev, &memri, &memr); + vkGetImageMemoryRequirements2(dev, &memri, &memr); int mem = vulkan_find_mem_type(renderer->dev, 0, memr.memoryRequirements.memoryTypeBits & fdp.memoryTypeBits); if (mem < 0) { @@ -712,7 +712,7 @@ VkImage vulkan_import_dmabuf(struct wlr_vk_renderer *renderer, } } - res = renderer->dev->api.vkBindImageMemory2KHR(dev, mem_count, bindi); + res = vkBindImageMemory2(dev, mem_count, bindi); if (res != VK_SUCCESS) { wlr_vk_error("vkBindMemory failed", res); goto error_image; diff --git a/render/vulkan/vulkan.c b/render/vulkan/vulkan.c index d1a0d77d3..78bc25941 100644 --- a/render/vulkan/vulkan.c +++ b/render/vulkan/vulkan.c @@ -81,6 +81,21 @@ static VKAPI_ATTR VkBool32 debug_callback(VkDebugUtilsMessageSeverityFlagBitsEXT } struct wlr_vk_instance *vulkan_instance_create(bool debug) { + // we require vulkan 1.1 + PFN_vkEnumerateInstanceVersion pfEnumInstanceVersion = + (PFN_vkEnumerateInstanceVersion) + vkGetInstanceProcAddr(VK_NULL_HANDLE, "vkEnumerateInstanceVersion"); + if (!pfEnumInstanceVersion) { + wlr_log(WLR_ERROR, "wlroots requires vulkan 1.1 which is not available"); + return NULL; + } + + uint32_t ini_version; + if (pfEnumInstanceVersion(&ini_version) != VK_SUCCESS || + ini_version < VK_API_VERSION_1_1) { + wlr_log(WLR_ERROR, "wlroots requires vulkan 1.1 which is not available"); + return NULL; + } uint32_t avail_extc = 0; VkResult res; @@ -110,18 +125,7 @@ struct wlr_vk_instance *vulkan_instance_create(bool debug) { } size_t extensions_len = 0; - const char *extensions[8] = {0}; - extensions[extensions_len++] = VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME; - extensions[extensions_len++] = VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME; - extensions[extensions_len++] = VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME; - - for (size_t i = 0; i < extensions_len; i++) { - if (!check_extension(avail_ext_props, avail_extc, extensions[i])) { - wlr_log(WLR_ERROR, "vulkan: required instance extension %s not found", - extensions[i]); - goto error; - } - } + const char *extensions[1] = {0}; bool debug_utils_found = false; if (debug && check_extension(avail_ext_props, avail_extc, @@ -136,7 +140,7 @@ struct wlr_vk_instance *vulkan_instance_create(bool debug) { .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, .pEngineName = "wlroots", .engineVersion = WLR_VERSION_NUM, - .apiVersion = VK_API_VERSION_1_0, + .apiVersion = VK_API_VERSION_1_1, }; VkInstanceCreateInfo instance_info = { @@ -278,10 +282,20 @@ VkPhysicalDevice vulkan_find_drm_phdev(struct wlr_vk_instance *ini, int drm_fd) for (uint32_t i = 0; i < num_phdevs; ++i) { VkPhysicalDevice phdev = phdevs[i]; + // check whether device supports vulkan 1.1, needed for + // vkGetPhysicalDeviceProperties2 VkPhysicalDeviceProperties phdev_props; vkGetPhysicalDeviceProperties(phdev, &phdev_props); + log_phdev(&phdev_props); + if (phdev_props.apiVersion < VK_API_VERSION_1_1) { + // NOTE: we could additionaly check whether the + // VkPhysicalDeviceProperties2KHR extension is supported but + // implementations not supporting 1.1 are unlikely in future + continue; + } + // check for extensions uint32_t avail_extc = 0; res = vkEnumerateDeviceExtensionProperties(phdev, NULL, @@ -460,12 +474,6 @@ struct wlr_vk_device *vulkan_device_create(struct wlr_vk_instance *ini, extensions[extensions_len++] = VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME; extensions[extensions_len++] = VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME; // or vulkan 1.2 extensions[extensions_len++] = VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME; // or vulkan 1.3 - extensions[extensions_len++] = VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME; // or vulkan 1.1 - extensions[extensions_len++] = VK_KHR_BIND_MEMORY_2_EXTENSION_NAME; // or vulkan 1.1 - extensions[extensions_len++] = VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME; // or vulkan 1.1 - extensions[extensions_len++] = VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME; // or vulkan 1.1 - extensions[extensions_len++] = VK_KHR_MAINTENANCE_1_EXTENSION_NAME; // or vulkan 1.1 - extensions[extensions_len++] = VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME; // or vulkan 1.1 for (size_t i = 0; i < extensions_len; i++) { if (!check_extension(avail_ext_props, avail_extc, extensions[i])) { @@ -622,10 +630,6 @@ struct wlr_vk_device *vulkan_device_create(struct wlr_vk_instance *ini, load_device_proc(dev, "vkGetSemaphoreCounterValueKHR", &dev->api.vkGetSemaphoreCounterValueKHR); load_device_proc(dev, "vkQueueSubmit2KHR", &dev->api.vkQueueSubmit2KHR); - load_device_proc(dev, "vkBindImageMemory2KHR", &dev->api.vkBindImageMemory2KHR); - load_device_proc(dev, "vkCreateSamplerYcbcrConversionKHR", &dev->api.vkCreateSamplerYcbcrConversionKHR); - load_device_proc(dev, "vkDestroySamplerYcbcrConversionKHR", &dev->api.vkDestroySamplerYcbcrConversionKHR); - load_device_proc(dev, "vkGetImageMemoryRequirements2KHR", &dev->api.vkGetImageMemoryRequirements2KHR); if (has_external_semaphore_fd) { load_device_proc(dev, "vkGetSemaphoreFdKHR", &dev->api.vkGetSemaphoreFdKHR); diff --git a/test/bench_scene.c b/test/bench_scene.c deleted file mode 100644 index 6d6b270f0..000000000 --- a/test/bench_scene.c +++ /dev/null @@ -1,154 +0,0 @@ -#include -#include -#include - -struct tree_spec { - // Parameters for the tree we'll construct - int depth; - int branching; - int rect_size; - int spread; - - // Stats around the tree we built - int tree_count; - int rect_count; - int max_x; - int max_y; -}; - -static int max(int a, int b) { - return a > b ? a : b; -} - -static double timespec_diff_msec(struct timespec *start, struct timespec *end) { - return (double)(end->tv_sec - start->tv_sec) * 1e3 + - (double)(end->tv_nsec - start->tv_nsec) / 1e6; -} - -static bool build_tree(struct wlr_scene_tree *parent, struct tree_spec *spec, - int depth, int x, int y) { - - if (depth == spec->depth) { - float color[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; - struct wlr_scene_rect *rect = - wlr_scene_rect_create(parent, spec->rect_size, spec->rect_size, color); - if (rect == NULL) { - fprintf(stderr, "wlr_scene_rect_create failed\n"); - return false; - } - wlr_scene_node_set_position(&rect->node, x, y); - spec->max_x = max(spec->max_x, x + spec->rect_size); - spec->max_y = max(spec->max_y, y + spec->rect_size); - spec->rect_count++; - return true; - } - - for (int i = 0; i < spec->branching; i++) { - struct wlr_scene_tree *child = wlr_scene_tree_create(parent); - if (child == NULL) { - fprintf(stderr, "wlr_scene_tree_create failed\n"); - return false; - } - spec->tree_count++; - int offset = i * spec->spread; - wlr_scene_node_set_position(&child->node, offset, offset); - if (!build_tree(child, spec, depth + 1, x + offset, y + offset)) { - return false; - } - } - return true; -} - -static bool bench_create_tree(struct wlr_scene *scene, struct tree_spec *spec) { - struct timespec start, end; - clock_gettime(CLOCK_MONOTONIC, &start); - if (!build_tree(&scene->tree, spec, 0, 0, 0)) { - fprintf(stderr, "build_tree failed\n"); - return false; - } - clock_gettime(CLOCK_MONOTONIC, &end); - - printf("Built tree with %d tree nodes, %d rect nodes\n\n", - spec->tree_count, spec->rect_count); - - double elapsed = timespec_diff_msec(&start, &end); - int nodes = spec->tree_count + spec->rect_count; - printf("create test tree: %d nodes, %.3f ms, %.0f nodes/ms\n", - nodes, elapsed, nodes / elapsed); - return true; -} - -static void bench_scene_node_at(struct wlr_scene *scene, struct tree_spec *spec) { - struct timespec start, end; - int iters = 10000; - int hits = 0; - - clock_gettime(CLOCK_MONOTONIC, &start); - for (int i = 0; i < iters; i++) { - // Spread lookups across the tree extent - double lx = (double)(i * 97 % spec->max_x); - double ly = (double)(i * 53 % spec->max_y); - double nx, ny; - struct wlr_scene_node *node = - wlr_scene_node_at(&scene->tree.node, lx, ly, &nx, &ny); - if (node != NULL) { - hits++; - } - } - clock_gettime(CLOCK_MONOTONIC, &end); - - double elapsed = timespec_diff_msec(&start, &end); - int nodes = (spec->tree_count + spec->rect_count) * iters; - printf("wlr_scene_node_at: %d iters, %.3f ms, %.0f nodes/ms (hits: %d/%d)\n", - iters, elapsed, nodes / elapsed, hits, iters); -} - -static void noop_iterator(struct wlr_scene_buffer *buffer, - int sx, int sy, void *user_data) { - (void)buffer; - (void)sx; - (void)sy; - int *cnt = user_data; - (*cnt)++; -} - -static void bench_scene_node_for_each_buffer(struct wlr_scene *scene, struct tree_spec *spec) { - struct timespec start, end; - int iters = 10000; - int hits = 0; - - clock_gettime(CLOCK_MONOTONIC, &start); - for (int i = 0; i < iters; i++) { - wlr_scene_node_for_each_buffer(&scene->tree.node, - noop_iterator, &hits); - } - clock_gettime(CLOCK_MONOTONIC, &end); - - double elapsed = timespec_diff_msec(&start, &end); - int nodes = (spec->tree_count + spec->rect_count) * iters; - printf("wlr_scene_node_for_each_buffer: %d iters, %.3f ms, %.0f nodes/ms (hits: %d/%d)\n", - iters, elapsed, nodes / elapsed, hits, iters); -} - -int main(void) { - struct wlr_scene *scene = wlr_scene_create(); - if (scene == NULL) { - fprintf(stderr, "wlr_scene_create failed\n"); - return 99; - } - - struct tree_spec spec = { - .depth = 5, - .branching = 5, - .rect_size = 10, - .spread = 100, - }; - if (!bench_create_tree(scene, &spec)) { - return 99; - } - bench_scene_node_at(scene, &spec); - bench_scene_node_for_each_buffer(scene, &spec); - - wlr_scene_node_destroy(&scene->tree.node); - return 0; -} diff --git a/test/meson.build b/test/meson.build deleted file mode 100644 index f51b2c02c..000000000 --- a/test/meson.build +++ /dev/null @@ -1,10 +0,0 @@ -test( - 'box', - executable('test-box', 'test_box.c', dependencies: wlroots), -) - -benchmark( - 'scene', - executable('bench-scene', 'bench_scene.c', dependencies: wlroots), - timeout: 30, -) diff --git a/test/test_box.c b/test/test_box.c deleted file mode 100644 index fcd95a8e2..000000000 --- a/test/test_box.c +++ /dev/null @@ -1,149 +0,0 @@ -#include -#include -#include - -static void test_box_empty(void) { - // NULL is empty - assert(wlr_box_empty(NULL)); - - // Zero width/height - struct wlr_box box = { .x = 0, .y = 0, .width = 0, .height = 10 }; - assert(wlr_box_empty(&box)); - box = (struct wlr_box){ .x = 0, .y = 0, .width = 10, .height = 0 }; - assert(wlr_box_empty(&box)); - - // Negative width/height - box = (struct wlr_box){ .x = 0, .y = 0, .width = -1, .height = 10 }; - assert(wlr_box_empty(&box)); - box = (struct wlr_box){ .x = 0, .y = 0, .width = 10, .height = -1 }; - assert(wlr_box_empty(&box)); - - // Valid box - box = (struct wlr_box){ .x = 0, .y = 0, .width = 10, .height = 10 }; - assert(!wlr_box_empty(&box)); -} - -static void test_box_intersection(void) { - struct wlr_box dest; - - // Overlapping - struct wlr_box a = { .x = 0, .y = 0, .width = 100, .height = 100 }; - struct wlr_box b = { .x = 50, .y = 50, .width = 100, .height = 100 }; - assert(wlr_box_intersection(&dest, &a, &b)); - assert(dest.x == 50 && dest.y == 50 && - dest.width == 50 && dest.height == 50); - - // Non-overlapping - b = (struct wlr_box){ .x = 200, .y = 200, .width = 50, .height = 50 }; - assert(!wlr_box_intersection(&dest, &a, &b)); - assert(dest.width == 0 && dest.height == 0); - - // Touching edges - b = (struct wlr_box){ .x = 100, .y = 0, .width = 50, .height = 50 }; - assert(!wlr_box_intersection(&dest, &a, &b)); - - // Self-intersection - assert(wlr_box_intersection(&dest, &a, &a)); - assert(dest.x == a.x && dest.y == a.y && - dest.width == a.width && dest.height == a.height); - - // Empty input - struct wlr_box empty = { .x = 0, .y = 0, .width = 0, .height = 0 }; - assert(!wlr_box_intersection(&dest, &a, &empty)); - - // NULL input - assert(!wlr_box_intersection(&dest, &a, NULL)); - assert(!wlr_box_intersection(&dest, NULL, &a)); -} - -static void test_box_intersects_box(void) { - // Overlapping - struct wlr_box a = { .x = 0, .y = 0, .width = 100, .height = 100 }; - struct wlr_box b = { .x = 50, .y = 50, .width = 100, .height = 100 }; - assert(wlr_box_intersects(&a, &b)); - - // Non-overlapping - b = (struct wlr_box){ .x = 200, .y = 200, .width = 50, .height = 50 }; - assert(!wlr_box_intersects(&a, &b)); - - // Touching edges - b = (struct wlr_box){ .x = 100, .y = 0, .width = 50, .height = 50 }; - assert(!wlr_box_intersects(&a, &b)); - - // Self-intersection - assert(wlr_box_intersects(&a, &a)); - - // Empty input - struct wlr_box empty = { .x = 0, .y = 0, .width = 0, .height = 0 }; - assert(!wlr_box_intersects(&a, &empty)); - - // NULL input - assert(!wlr_box_intersects(&a, NULL)); - assert(!wlr_box_intersects(NULL, &a)); -} - -static void test_box_contains_point(void) { - struct wlr_box box = { .x = 10, .y = 20, .width = 100, .height = 50 }; - - // Interior point - assert(wlr_box_contains_point(&box, 50, 40)); - - // Inclusive lower bound - assert(wlr_box_contains_point(&box, 10, 20)); - - // Exclusive upper bound - assert(!wlr_box_contains_point(&box, 110, 70)); - assert(!wlr_box_contains_point(&box, 110, 40)); - assert(!wlr_box_contains_point(&box, 50, 70)); - - // Outside - assert(!wlr_box_contains_point(&box, 5, 40)); - assert(!wlr_box_contains_point(&box, 50, 15)); - - // Empty box - struct wlr_box empty = { .x = 0, .y = 0, .width = 0, .height = 0 }; - assert(!wlr_box_contains_point(&empty, 0, 0)); - - // NULL - assert(!wlr_box_contains_point(NULL, 0, 0)); -} - -static void test_box_contains_box(void) { - struct wlr_box outer = { .x = 0, .y = 0, .width = 100, .height = 100 }; - - // Fully contained - struct wlr_box inner = { .x = 10, .y = 10, .width = 50, .height = 50 }; - assert(wlr_box_contains_box(&outer, &inner)); - - // Self-containment - assert(wlr_box_contains_box(&outer, &outer)); - - // Partial overlap — not contained - struct wlr_box partial = { .x = 50, .y = 50, .width = 100, .height = 100 }; - assert(!wlr_box_contains_box(&outer, &partial)); - - // Empty inner - struct wlr_box empty = { .x = 0, .y = 0, .width = 0, .height = 0 }; - assert(!wlr_box_contains_box(&outer, &empty)); - - // Empty outer - assert(!wlr_box_contains_box(&empty, &inner)); - - // NULL - assert(!wlr_box_contains_box(&outer, NULL)); - assert(!wlr_box_contains_box(NULL, &outer)); -} - -int main(void) { -#ifdef NDEBUG - fprintf(stderr, "NDEBUG must be disabled for tests\n"); - return 1; -#endif - - test_box_empty(); - test_box_intersection(); - test_box_intersects_box(); - test_box_contains_point(); - test_box_contains_box(); - return 0; -} diff --git a/tinywl/Makefile b/tinywl/Makefile index 0f1c4cb13..2efe4a436 100644 --- a/tinywl/Makefile +++ b/tinywl/Makefile @@ -1,6 +1,6 @@ PKG_CONFIG?=pkg-config -PKGS="wlroots-0.21" wayland-server xkbcommon +PKGS="wlroots-0.20" wayland-server xkbcommon CFLAGS_PKG_CONFIG!=$(PKG_CONFIG) --cflags $(PKGS) CFLAGS+=$(CFLAGS_PKG_CONFIG) LIBS!=$(PKG_CONFIG) --libs $(PKGS) diff --git a/tinywl/tinywl.c b/tinywl/tinywl.c index fe242e1a9..b3d902c7e 100644 --- a/tinywl/tinywl.c +++ b/tinywl/tinywl.c @@ -614,7 +614,7 @@ static void server_new_output(struct wl_listener *listener, void *data) { struct wlr_output *wlr_output = data; /* Configures the output created by the backend to use our allocator - * and our renderer. Must be done once, before committing the output */ + * and our renderer. Must be done once, before commiting the output */ wlr_output_init_render(wlr_output, server->allocator, server->renderer); /* The output may be disabled, switch it on. */ @@ -723,7 +723,7 @@ static void xdg_toplevel_destroy(struct wl_listener *listener, void *data) { static void begin_interactive(struct tinywl_toplevel *toplevel, enum tinywl_cursor_mode mode, uint32_t edges) { /* This function sets up an interactive move or resize operation, where the - * compositor stops propagating pointer events to clients and instead + * compositor stops propegating pointer events to clients and instead * consumes them itself, to move or resize windows. */ struct tinywl_server *server = toplevel->server; @@ -906,7 +906,7 @@ int main(int argc, char *argv[]) { struct tinywl_server server = {0}; /* The Wayland display is managed by libwayland. It handles accepting - * clients from the Unix socket, managing Wayland globals, and so on. */ + * clients from the Unix socket, manging Wayland globals, and so on. */ server.wl_display = wl_display_create(); /* The backend is a wlroots feature which abstracts the underlying input and * output hardware. The autocreate option will choose the most suitable diff --git a/types/buffer/buffer.c b/types/buffer/buffer.c index 48a10d9f0..d56255b0d 100644 --- a/types/buffer/buffer.c +++ b/types/buffer/buffer.c @@ -109,11 +109,14 @@ bool wlr_buffer_get_shm(struct wlr_buffer *buffer, bool wlr_buffer_is_opaque(struct wlr_buffer *buffer) { void *data; - uint32_t format = buffer_get_drm_format(buffer); + uint32_t format; size_t stride; - - if (format != DRM_FORMAT_INVALID) { - // pass + struct wlr_dmabuf_attributes dmabuf; + struct wlr_shm_attributes shm; + if (wlr_buffer_get_dmabuf(buffer, &dmabuf)) { + format = dmabuf.format; + } else if (wlr_buffer_get_shm(buffer, &shm)) { + format = shm.format; } else if (wlr_buffer_begin_data_ptr_access(buffer, WLR_BUFFER_DATA_PTR_ACCESS_READ, &data, &format, &stride)) { bool opaque = false; @@ -132,15 +135,3 @@ bool wlr_buffer_is_opaque(struct wlr_buffer *buffer) { return !pixel_format_has_alpha(format); } - -uint32_t buffer_get_drm_format(struct wlr_buffer *buffer) { - uint32_t format = DRM_FORMAT_INVALID; - struct wlr_dmabuf_attributes dmabuf; - struct wlr_shm_attributes shm; - if (wlr_buffer_get_dmabuf(buffer, &dmabuf)) { - format = dmabuf.format; - } else if (wlr_buffer_get_shm(buffer, &shm)) { - format = shm.format; - } - return format; -} diff --git a/types/ext_image_capture_source_v1/output.c b/types/ext_image_capture_source_v1/output.c index 0e3a57823..75fa15f4d 100644 --- a/types/ext_image_capture_source_v1/output.c +++ b/types/ext_image_capture_source_v1/output.c @@ -110,10 +110,6 @@ static const struct wlr_ext_image_capture_source_v1_interface output_source_impl static void source_update_buffer_constraints(struct wlr_ext_output_image_capture_source_v1 *source) { struct wlr_output *output = source->output; - if (!output->enabled) { - return; - } - if (!wlr_output_configure_primary_swapchain(output, NULL, &output->swapchain)) { return; } @@ -127,8 +123,7 @@ static void source_handle_output_commit(struct wl_listener *listener, struct wlr_ext_output_image_capture_source_v1 *source = wl_container_of(listener, source, output_commit); struct wlr_output_event_commit *event = data; - if (event->state->committed & (WLR_OUTPUT_STATE_MODE | - WLR_OUTPUT_STATE_RENDER_FORMAT | WLR_OUTPUT_STATE_ENABLED)) { + if (event->state->committed & (WLR_OUTPUT_STATE_MODE | WLR_OUTPUT_STATE_RENDER_FORMAT)) { source_update_buffer_constraints(source); } diff --git a/types/ext_image_capture_source_v1/scene.c b/types/ext_image_capture_source_v1/scene.c index 99d34e012..d3bf86b6c 100644 --- a/types/ext_image_capture_source_v1/scene.c +++ b/types/ext_image_capture_source_v1/scene.c @@ -173,6 +173,8 @@ static void source_update_buffer_constraints(struct scene_node_source *source, } static bool output_test(struct wlr_output *output, const struct wlr_output_state *state) { + struct scene_node_source *source = wl_container_of(output, source, output); + uint32_t supported = WLR_OUTPUT_STATE_BACKEND_OPTIONAL | WLR_OUTPUT_STATE_BUFFER | diff --git a/types/output/cursor.c b/types/output/cursor.c index 4a823dab1..11f442cdf 100644 --- a/types/output/cursor.c +++ b/types/output/cursor.c @@ -159,8 +159,9 @@ static void output_cursor_update_visible(struct wlr_output_cursor *cursor) { struct wlr_box cursor_box; output_cursor_get_box(cursor, &cursor_box); + struct wlr_box intersection; cursor->visible = - wlr_box_intersects(&output_box, &cursor_box); + wlr_box_intersection(&intersection, &output_box, &cursor_box); } static bool output_pick_cursor_format(struct wlr_output *output, @@ -534,4 +535,4 @@ bool output_cursor_refresh_color_transform(struct wlr_output_cursor *output_curs wlr_color_transform_unref(transforms[0]); wlr_color_transform_unref(transforms[1]); return output_cursor->color_transform != NULL; -} +} \ No newline at end of file diff --git a/types/output/output.c b/types/output/output.c index 46da1f425..3715950ce 100644 --- a/types/output/output.c +++ b/types/output/output.c @@ -233,11 +233,6 @@ static void output_apply_state(struct wlr_output *output, output->transform = state->transform; } - if (state->committed & WLR_OUTPUT_STATE_COLOR_REPRESENTATION) { - output->color_encoding = state->color_encoding; - output->color_range = state->color_range; - } - if (state->committed & WLR_OUTPUT_STATE_IMAGE_DESCRIPTION) { if (state->image_description != NULL) { output->image_description_value = *state->image_description; @@ -585,11 +580,6 @@ static uint32_t output_compare_state(struct wlr_output *output, output->color_transform == state->color_transform) { fields |= WLR_OUTPUT_STATE_COLOR_TRANSFORM; } - if ((state->committed & WLR_OUTPUT_STATE_COLOR_REPRESENTATION) && - output->color_encoding == state->color_encoding && - output->color_range == state->color_range) { - fields |= WLR_OUTPUT_STATE_COLOR_REPRESENTATION; - } return fields; } @@ -625,7 +615,7 @@ static bool output_basic_test(struct wlr_output *output, }; struct wlr_box dst_box; output_state_get_buffer_dst_box(state, &dst_box); - if (!wlr_box_intersects(&output_box, &dst_box)) { + if (!wlr_box_intersection(&output_box, &output_box, &dst_box)) { wlr_log(WLR_ERROR, "Primary buffer is entirely off-screen or 0-sized"); return false; } @@ -642,10 +632,6 @@ static bool output_basic_test(struct wlr_output *output, wlr_log(WLR_DEBUG, "Tried to set signal timeline without a buffer"); return false; } - if (state->committed & WLR_OUTPUT_STATE_COLOR_REPRESENTATION) { - wlr_log(WLR_DEBUG, "Tried to set color representation without a buffer"); - return false; - } } if (state->committed & WLR_OUTPUT_STATE_RENDER_FORMAT) { diff --git a/types/output/state.c b/types/output/state.c index 5f44c18e8..f2c655e21 100644 --- a/types/output/state.c +++ b/types/output/state.c @@ -141,14 +141,6 @@ bool wlr_output_state_set_image_description(struct wlr_output_state *state, return true; } -void wlr_output_state_set_color_encoding_and_range( - struct wlr_output_state *state, - enum wlr_color_encoding encoding, enum wlr_color_range range) { - state->committed |= WLR_OUTPUT_STATE_COLOR_REPRESENTATION; - state->color_encoding = encoding; - state->color_range = range; -} - bool wlr_output_state_copy(struct wlr_output_state *dst, const struct wlr_output_state *src) { struct wlr_output_state copy = *src; diff --git a/types/scene/layer_shell_v1.c b/types/scene/layer_shell_v1.c index 234227df1..4ae736ddf 100644 --- a/types/scene/layer_shell_v1.c +++ b/types/scene/layer_shell_v1.c @@ -1,7 +1,6 @@ #include #include #include -#include static void scene_layer_surface_handle_tree_destroy( struct wl_listener *listener, void *data) { @@ -22,23 +21,36 @@ static void scene_layer_surface_handle_layer_surface_destroy( static void layer_surface_exclusive_zone( struct wlr_layer_surface_v1_state *state, - enum wlr_edges edge, struct wlr_box *usable_area) { - switch (edge) { - case WLR_EDGE_NONE: - return; - case WLR_EDGE_TOP: + switch (state->anchor) { + case ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP: + case (ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | + ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | + ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT): + // Anchor top usable_area->y += state->exclusive_zone + state->margin.top; usable_area->height -= state->exclusive_zone + state->margin.top; break; - case WLR_EDGE_BOTTOM: + case ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM: + case (ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM | + ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | + ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT): + // Anchor bottom usable_area->height -= state->exclusive_zone + state->margin.bottom; break; - case WLR_EDGE_LEFT: + case ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT: + case (ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | + ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM | + ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT): + // Anchor left usable_area->x += state->exclusive_zone + state->margin.left; usable_area->width -= state->exclusive_zone + state->margin.left; break; - case WLR_EDGE_RIGHT: + case ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT: + case (ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | + ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM | + ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT): + // Anchor right usable_area->width -= state->exclusive_zone + state->margin.right; break; } @@ -109,8 +121,7 @@ void wlr_scene_layer_surface_v1_configure( wlr_layer_surface_v1_configure(layer_surface, box.width, box.height); if (layer_surface->surface->mapped && state->exclusive_zone > 0) { - enum wlr_edges edge = wlr_layer_surface_v1_get_exclusive_edge(layer_surface); - layer_surface_exclusive_zone(state, edge, usable_area); + layer_surface_exclusive_zone(state, usable_area); } } diff --git a/types/scene/surface.c b/types/scene/surface.c index e6ea1333a..bce8c74a6 100644 --- a/types/scene/surface.c +++ b/types/scene/surface.c @@ -38,7 +38,7 @@ static struct wlr_output *get_surface_frame_pacing_output(struct wlr_surface *su return frame_pacing_output; } -static int get_tf_preference(enum wlr_color_transfer_function tf) { +static bool get_tf_preference(enum wlr_color_transfer_function tf) { switch (tf) { case WLR_COLOR_TRANSFER_FUNCTION_GAMMA22: return 0; @@ -52,7 +52,7 @@ static int get_tf_preference(enum wlr_color_transfer_function tf) { abort(); // unreachable } -static int get_primaries_preference(enum wlr_color_named_primaries primaries) { +static bool get_primaries_preference(enum wlr_color_named_primaries primaries) { switch (primaries) { case WLR_COLOR_NAMED_PRIMARIES_SRGB: return 0; @@ -94,44 +94,14 @@ static void handle_scene_buffer_outputs_update( struct wl_listener *listener, void *data) { struct wlr_scene_surface *surface = wl_container_of(listener, surface, outputs_update); - struct wlr_scene_outputs_update_event *event = data; struct wlr_scene *scene = scene_node_get_root(&surface->buffer->node); // If the surface is no longer visible on any output, keep the last sent // preferred configuration to avoid unnecessary redraws - if (event->size == 0) { + if (wl_list_empty(&surface->surface->current_outputs)) { return; } - // To avoid sending redundant leave/enter events when a surface is hidden and then shown - // without moving to a different output the following policy is implemented: - // - // 1. When a surface transitions from being visible on >0 outputs to being visible on 0 outputs - // don't send any leave events. - // - // 2. When a surface transitions from being visible on 0 outputs to being visible on >0 outputs - // send leave events for all entered outputs on which the surface is no longer visible as - // well as enter events for any outputs not already entered. - struct wlr_surface_output *entered_output, *tmp; - wl_list_for_each_safe(entered_output, tmp, &surface->surface->current_outputs, link) { - bool active = false; - for (size_t i = 0; i < event->size; i++) { - if (entered_output->output == event->active[i]->output) { - active = true; - break; - } - } - if (!active) { - wlr_surface_send_leave(surface->surface, entered_output->output); - } - } - - for (size_t i = 0; i < event->size; i++) { - // This function internally checks if an enter event was already sent for the output - // to avoid sending redundant events. - wlr_surface_send_enter(surface->surface, event->active[i]->output); - } - double scale = get_surface_preferred_buffer_scale(surface->surface); wlr_fractional_scale_v1_notify_scale(surface->surface, scale); wlr_surface_set_preferred_buffer_scale(surface->surface, ceil(scale)); @@ -144,6 +114,24 @@ static void handle_scene_buffer_outputs_update( } } +static void handle_scene_buffer_output_enter( + struct wl_listener *listener, void *data) { + struct wlr_scene_surface *surface = + wl_container_of(listener, surface, output_enter); + struct wlr_scene_output *output = data; + + wlr_surface_send_enter(surface->surface, output->output); +} + +static void handle_scene_buffer_output_leave( + struct wl_listener *listener, void *data) { + struct wlr_scene_surface *surface = + wl_container_of(listener, surface, output_leave); + struct wlr_scene_output *output = data; + + wlr_surface_send_leave(surface->surface, output->output); +} + static void handle_scene_buffer_output_sample( struct wl_listener *listener, void *data) { struct wlr_scene_surface *surface = @@ -159,13 +147,6 @@ static void handle_scene_buffer_output_sample( } else { wlr_presentation_surface_textured_on_output(surface->surface, output); } - - struct wlr_linux_drm_syncobj_surface_v1_state *syncobj_surface_state = - wlr_linux_drm_syncobj_v1_get_surface_state(surface->surface); - if (syncobj_surface_state != NULL && event->release_timeline != NULL) { - wlr_linux_drm_syncobj_v1_state_add_release_point(syncobj_surface_state, - event->release_timeline, event->release_point, output->event_loop); - } } static void handle_scene_buffer_frame_done( @@ -330,15 +311,27 @@ static void surface_reconfigure(struct wlr_scene_surface *scene_surface) { struct wlr_linux_drm_syncobj_surface_v1_state *syncobj_surface_state = wlr_linux_drm_syncobj_v1_get_surface_state(surface); + struct wlr_drm_syncobj_timeline *wait_timeline = NULL; + uint64_t wait_point = 0; + if (syncobj_surface_state != NULL) { + wait_timeline = syncobj_surface_state->acquire_timeline; + wait_point = syncobj_surface_state->acquire_point; + } + struct wlr_scene_buffer_set_buffer_options options = { .damage = &surface->buffer_damage, + .wait_timeline = wait_timeline, + .wait_point = wait_point, }; - if (syncobj_surface_state != NULL) { - options.wait_timeline = syncobj_surface_state->acquire_timeline; - options.wait_point = syncobj_surface_state->acquire_point; - } wlr_scene_buffer_set_buffer_with_options(scene_buffer, &surface->buffer->base, &options); + + if (syncobj_surface_state != NULL && + (surface->current.committed & WLR_SURFACE_STATE_BUFFER) && + surface->buffer->source != NULL) { + wlr_linux_drm_syncobj_v1_state_signal_release_with_buffer(syncobj_surface_state, + surface->buffer->source); + } } else { wlr_scene_buffer_set_buffer(scene_buffer, NULL); } @@ -387,6 +380,8 @@ static void surface_addon_destroy(struct wlr_addon *addon) { wlr_addon_finish(&surface->addon); wl_list_remove(&surface->outputs_update.link); + wl_list_remove(&surface->output_enter.link); + wl_list_remove(&surface->output_leave.link); wl_list_remove(&surface->output_sample.link); wl_list_remove(&surface->frame_done.link); wl_list_remove(&surface->surface_destroy.link); @@ -432,6 +427,12 @@ struct wlr_scene_surface *wlr_scene_surface_create(struct wlr_scene_tree *parent surface->outputs_update.notify = handle_scene_buffer_outputs_update; wl_signal_add(&scene_buffer->events.outputs_update, &surface->outputs_update); + surface->output_enter.notify = handle_scene_buffer_output_enter; + wl_signal_add(&scene_buffer->events.output_enter, &surface->output_enter); + + surface->output_leave.notify = handle_scene_buffer_output_leave; + wl_signal_add(&scene_buffer->events.output_leave, &surface->output_leave); + surface->output_sample.notify = handle_scene_buffer_output_sample; wl_signal_add(&scene_buffer->events.output_sample, &surface->output_sample); diff --git a/types/scene/wlr_scene.c b/types/scene/wlr_scene.c index 7231422e8..19617b11f 100644 --- a/types/scene/wlr_scene.c +++ b/types/scene/wlr_scene.c @@ -113,11 +113,24 @@ void wlr_scene_node_destroy(struct wlr_scene_node *node) { if (node->type == WLR_SCENE_NODE_BUFFER) { struct wlr_scene_buffer *scene_buffer = wlr_scene_buffer_from_node(node); + uint64_t active = scene_buffer->active_outputs; + if (active) { + struct wlr_scene_output *scene_output; + wl_list_for_each(scene_output, &scene->outputs, link) { + if (active & (1ull << scene_output->index)) { + wl_signal_emit_mutable(&scene_buffer->events.output_leave, + scene_output); + } + } + } + scene_buffer_set_buffer(scene_buffer, NULL); scene_buffer_set_texture(scene_buffer, NULL); pixman_region32_fini(&scene_buffer->opaque_region); wlr_drm_syncobj_timeline_unref(scene_buffer->wait_timeline); + assert(wl_list_empty(&scene_buffer->events.output_leave.listener_list)); + assert(wl_list_empty(&scene_buffer->events.output_enter.listener_list)); assert(wl_list_empty(&scene_buffer->events.outputs_update.listener_list)); assert(wl_list_empty(&scene_buffer->events.output_sample.listener_list)); assert(wl_list_empty(&scene_buffer->events.frame_done.listener_list)); @@ -225,7 +238,7 @@ static bool _scene_nodes_in_box(struct wlr_scene_node *node, struct wlr_box *box struct wlr_box node_box = { .x = lx, .y = ly }; scene_node_get_size(node, &node_box.width, &node_box.height); - if (wlr_box_intersects(&node_box, box) && + if (wlr_box_intersection(&node_box, &node_box, box) && iterator(node, lx, ly, user_data)) { return true; } @@ -468,12 +481,28 @@ static void update_node_update_outputs(struct wlr_scene_node *node, (struct wlr_linux_dmabuf_feedback_v1_init_options){0}; } + uint64_t old_active = scene_buffer->active_outputs; + scene_buffer->active_outputs = active_outputs; + + struct wlr_scene_output *scene_output; + wl_list_for_each(scene_output, outputs, link) { + uint64_t mask = 1ull << scene_output->index; + bool intersects = active_outputs & mask; + bool intersects_before = old_active & mask; + + if (intersects && !intersects_before) { + wl_signal_emit_mutable(&scene_buffer->events.output_enter, scene_output); + } else if (!intersects && intersects_before) { + wl_signal_emit_mutable(&scene_buffer->events.output_leave, scene_output); + } + } + // if there are active outputs on this node, we should always have a primary // output - assert(!active_outputs || scene_buffer->primary_output); + assert(!scene_buffer->active_outputs || scene_buffer->primary_output); // Skip output update event if nothing was updated - if (scene_buffer->active_outputs == active_outputs && + if (old_active == active_outputs && (!force || ((1ull << force->index) & ~active_outputs)) && old_primary_output == scene_buffer->primary_output) { return; @@ -486,7 +515,6 @@ static void update_node_update_outputs(struct wlr_scene_node *node, }; size_t i = 0; - struct wlr_scene_output *scene_output; wl_list_for_each(scene_output, outputs, link) { if (~active_outputs & (1ull << scene_output->index)) { continue; @@ -496,7 +524,6 @@ static void update_node_update_outputs(struct wlr_scene_node *node, outputs_array[i++] = scene_output; } - scene_buffer->active_outputs = active_outputs; wl_signal_emit_mutable(&scene_buffer->events.outputs_update, &event); } @@ -842,6 +869,8 @@ struct wlr_scene_buffer *wlr_scene_buffer_create(struct wlr_scene_tree *parent, scene_node_init(&scene_buffer->node, WLR_SCENE_NODE_BUFFER, parent); wl_signal_init(&scene_buffer->events.outputs_update); + wl_signal_init(&scene_buffer->events.output_enter); + wl_signal_init(&scene_buffer->events.output_leave); wl_signal_init(&scene_buffer->events.output_sample); wl_signal_init(&scene_buffer->events.frame_done); @@ -1524,8 +1553,6 @@ static void scene_entry_render(struct render_list_entry *entry, const struct ren struct wlr_scene_output_sample_event sample_event = { .output = data->output, .direct_scanout = false, - .release_timeline = data->output->in_timeline, - .release_point = data->output->in_point, }; wl_signal_emit_mutable(&scene_buffer->events.output_sample, &sample_event); @@ -1758,10 +1785,7 @@ struct wlr_scene_output *wlr_scene_output_create(struct wlr_scene *scene, if (drm_fd >= 0 && output->backend->features.timeline && output->renderer != NULL && output->renderer->features.timeline) { scene_output->in_timeline = wlr_drm_syncobj_timeline_create(drm_fd); - scene_output->out_timeline = wlr_drm_syncobj_timeline_create(drm_fd); - if (scene_output->in_timeline == NULL || scene_output->out_timeline == NULL) { - wlr_drm_syncobj_timeline_unref(scene_output->in_timeline); - wlr_drm_syncobj_timeline_unref(scene_output->out_timeline); + if (scene_output->in_timeline == NULL) { return NULL; } } @@ -1816,14 +1840,7 @@ void wlr_scene_output_destroy(struct wlr_scene_output *scene_output) { wl_list_remove(&scene_output->output_commit.link); wl_list_remove(&scene_output->output_damage.link); wl_list_remove(&scene_output->output_needs_frame.link); - if (scene_output->in_timeline != NULL) { - wlr_drm_syncobj_timeline_signal(scene_output->in_timeline, UINT64_MAX); - wlr_drm_syncobj_timeline_unref(scene_output->in_timeline); - } - if (scene_output->out_timeline != NULL) { - wlr_drm_syncobj_timeline_signal(scene_output->out_timeline, UINT64_MAX); - wlr_drm_syncobj_timeline_unref(scene_output->out_timeline); - } + wlr_drm_syncobj_timeline_unref(scene_output->in_timeline); wlr_color_transform_unref(scene_output->gamma_lut_color_transform); wlr_color_transform_unref(scene_output->prev_gamma_lut_color_transform); wlr_color_transform_unref(scene_output->prev_supplied_color_transform); @@ -2069,6 +2086,11 @@ static enum scene_direct_scanout_result scene_entry_try_direct_scanout( return SCANOUT_INELIGIBLE; } + if (buffer->color_encoding != WLR_COLOR_ENCODING_NONE || + buffer->color_range != WLR_COLOR_RANGE_NONE) { + return SCANOUT_INELIGIBLE; + } + // We want to ensure optimal buffer selection, but as direct-scanout can be enabled and disabled // on a frame-by-frame basis, we wait for a few frames to send the new format recommendations. // Maybe we should only send feedback in this case if tests fail. @@ -2110,23 +2132,6 @@ static enum scene_direct_scanout_result scene_entry_try_direct_scanout( if (buffer->wait_timeline != NULL) { wlr_output_state_set_wait_timeline(&pending, buffer->wait_timeline, buffer->wait_point); } - - if (scene_output->out_timeline) { - scene_output->out_point++; - wlr_output_state_set_signal_timeline(&pending, scene_output->out_timeline, scene_output->out_point); - } - - if (buffer->color_encoding == WLR_COLOR_ENCODING_IDENTITY && - buffer->color_range == WLR_COLOR_RANGE_FULL) { - // IDENTITY+FULL (used for RGB formats) is equivalent to no color - // representation being set at all. - wlr_output_state_set_color_encoding_and_range(&pending, - WLR_COLOR_ENCODING_NONE, WLR_COLOR_RANGE_NONE); - } else { - wlr_output_state_set_color_encoding_and_range(&pending, - buffer->color_encoding, buffer->color_range); - } - if (!wlr_output_test_state(scene_output->output, &pending)) { wlr_output_state_finish(&pending); return SCANOUT_CANDIDATE; @@ -2138,8 +2143,6 @@ static enum scene_direct_scanout_result scene_entry_try_direct_scanout( struct wlr_scene_output_sample_event sample_event = { .output = scene_output, .direct_scanout = true, - .release_timeline = data->output->out_timeline, - .release_point = data->output->out_point, }; wl_signal_emit_mutable(&buffer->events.output_sample, &sample_event); return SCANOUT_SUCCESS; @@ -2384,7 +2387,7 @@ bool wlr_scene_output_build_state(struct wlr_scene_output *scene_output, pixman_region32_init(&acc_damage); struct highlight_region *damage, *tmp_damage; wl_list_for_each_safe(damage, tmp_damage, regions, link) { - // remove overlapping damage regions + // remove overlaping damage regions pixman_region32_subtract(&damage->region, &damage->region, &acc_damage); pixman_region32_union(&acc_damage, &acc_damage, &damage->region); @@ -2599,9 +2602,6 @@ bool wlr_scene_output_build_state(struct wlr_scene_output *scene_output, if (scene_output->in_timeline != NULL) { wlr_output_state_set_wait_timeline(state, scene_output->in_timeline, scene_output->in_point); - scene_output->out_point++; - wlr_output_state_set_signal_timeline(state, scene_output->out_timeline, - scene_output->out_point); } if (!render_gamma_lut) { @@ -2669,7 +2669,8 @@ static void scene_output_for_each_scene_buffer(const struct wlr_box *output_box, struct wlr_box node_box = { .x = lx, .y = ly }; scene_node_get_size(node, &node_box.width, &node_box.height); - if (wlr_box_intersects(output_box, &node_box)) { + struct wlr_box intersection; + if (wlr_box_intersection(&intersection, output_box, &node_box)) { struct wlr_scene_buffer *scene_buffer = wlr_scene_buffer_from_node(node); user_iterator(scene_buffer, lx, ly, user_data); diff --git a/types/wlr_color_management_v1.c b/types/wlr_color_management_v1.c index aa924e36d..0a19e8e78 100644 --- a/types/wlr_color_management_v1.c +++ b/types/wlr_color_management_v1.c @@ -74,41 +74,6 @@ static float decode_cie1931_coord(int32_t raw) { return (float)raw / (1000 * 1000); } -static bool cie1931_xy_equal(const struct wlr_color_cie1931_xy *a, - const struct wlr_color_cie1931_xy *b) { - return a->x == b->x && a->y == b->y; -} - -static bool primaries_equal(const struct wlr_color_primaries *a, - const struct wlr_color_primaries *b) { - return cie1931_xy_equal(&a->red, &b->red) && - cie1931_xy_equal(&a->green, &b->green) && - cie1931_xy_equal(&a->blue, &b->blue) && - cie1931_xy_equal(&a->white, &b->white); -} - -static bool img_desc_data_equal(const struct wlr_image_description_v1_data *a, - const struct wlr_image_description_v1_data *b) { - if (a->tf_named != b->tf_named || - a->primaries_named != b->primaries_named || - a->has_mastering_display_primaries != b->has_mastering_display_primaries || - a->has_mastering_luminance != b->has_mastering_luminance || - a->max_cll != b->max_cll || - a->max_fall != b->max_fall) { - return false; - } - if (a->has_mastering_display_primaries && - !primaries_equal(&a->mastering_display_primaries, &b->mastering_display_primaries)) { - return false; - } - if (a->has_mastering_luminance && - (a->mastering_luminance.min != b->mastering_luminance.min || - a->mastering_luminance.max != b->mastering_luminance.max)) { - return false; - } - return true; -} - static const struct wp_image_description_v1_interface image_desc_impl; static struct wlr_image_description_v1 *image_desc_from_resource(struct wl_resource *resource) { @@ -1037,20 +1002,16 @@ void wlr_color_manager_v1_set_surface_preferred_image_description( struct wlr_color_management_surface_feedback_v1 *surface_feedback; wl_list_for_each(surface_feedback, &manager->surface_feedbacks, link) { - if (surface_feedback->surface != surface || - img_desc_data_equal(&surface_feedback->data, data)) { - continue; - } - - surface_feedback->data = *data; - - uint32_t version = wl_resource_get_version(surface_feedback->resource); - if (version >= WP_COLOR_MANAGEMENT_SURFACE_FEEDBACK_V1_PREFERRED_CHANGED2_SINCE_VERSION) { - wp_color_management_surface_feedback_v1_send_preferred_changed2( - surface_feedback->resource, identity_hi, identity_lo); - } else { - wp_color_management_surface_feedback_v1_send_preferred_changed( - surface_feedback->resource, identity_lo); + if (surface_feedback->surface == surface) { + surface_feedback->data = *data; + uint32_t version = wl_resource_get_version(surface_feedback->resource); + if (version >= WP_COLOR_MANAGEMENT_SURFACE_FEEDBACK_V1_PREFERRED_CHANGED2_SINCE_VERSION) { + wp_color_management_surface_feedback_v1_send_preferred_changed2( + surface_feedback->resource, identity_hi, identity_lo); + } else { + wp_color_management_surface_feedback_v1_send_preferred_changed( + surface_feedback->resource, identity_lo); + } } } } diff --git a/types/wlr_color_representation_v1.c b/types/wlr_color_representation_v1.c index 856dc84f8..a447d77a7 100644 --- a/types/wlr_color_representation_v1.c +++ b/types/wlr_color_representation_v1.c @@ -1,17 +1,13 @@ #include -#include #include #include -#include #include #include #include #include #include "color-representation-v1-protocol.h" -#include "render/pixel_format.h" -#include "types/wlr_buffer.h" #include "util/mem.h" #define WP_COLOR_REPRESENTATION_VERSION 1 @@ -234,44 +230,8 @@ static void color_repr_manager_handle_destroy(struct wl_client *client, wl_resource_destroy(resource); } -static void surface_synced_commit(struct wlr_surface_synced *synced) { - struct wlr_color_representation_v1 *color_repr = wl_container_of(synced, color_repr, synced); - - if (color_repr->current.coefficients == 0 && color_repr->current.range == 0) { - return; - } - - uint32_t drm_format = DRM_FORMAT_INVALID; - if (color_repr->surface->buffer){ - drm_format = buffer_get_drm_format(&color_repr->surface->buffer->base); - } - if (drm_format == DRM_FORMAT_INVALID) { - return; - } - bool is_ycbcr = pixel_format_is_ycbcr(drm_format); - - bool is_identity_full = - color_repr->current.coefficients == WP_COLOR_REPRESENTATION_SURFACE_V1_COEFFICIENTS_IDENTITY && - color_repr->current.range == WP_COLOR_REPRESENTATION_SURFACE_V1_RANGE_FULL; - - if (is_ycbcr) { - if (is_identity_full) { - wl_resource_post_error(color_repr->resource, - WP_COLOR_REPRESENTATION_SURFACE_V1_ERROR_PIXEL_FORMAT, - "unexpected encoding/range for yuv"); - } - } else /* rgb */ { - if (!is_identity_full) { - wl_resource_post_error(color_repr->resource, - WP_COLOR_REPRESENTATION_SURFACE_V1_ERROR_PIXEL_FORMAT, - "unexpected encoding/range for rgb"); - } - } -} - static const struct wlr_surface_synced_impl surface_synced_impl = { .state_size = sizeof(struct wlr_color_representation_v1_surface_state), - .commit = surface_synced_commit }; static struct wlr_color_representation_v1 *color_repr_from_surface( @@ -316,7 +276,6 @@ static void color_repr_manager_handle_get_surface(struct wl_client *client, } color_repr->manager = manager_from_resource(manager_resource); - color_repr->surface = surface; if (!wlr_surface_synced_init(&color_repr->synced, surface, &surface_synced_impl, &color_repr->pending, &color_repr->current)) { @@ -468,10 +427,6 @@ struct wlr_color_representation_manager_v1 *wlr_color_representation_manager_v1_ struct wlr_color_representation_v1_coeffs_and_range coeffs_and_ranges[COEFFICIENTS_LEN * RANGES_LEN]; size_t coeffs_and_ranges_len = 0; - coeffs_and_ranges[coeffs_and_ranges_len++] = (struct wlr_color_representation_v1_coeffs_and_range){ - .coeffs = WP_COLOR_REPRESENTATION_SURFACE_V1_COEFFICIENTS_IDENTITY, - .range = WP_COLOR_REPRESENTATION_SURFACE_V1_RANGE_FULL, - }; for (size_t i = 0; i < COEFFICIENTS_LEN; i++) { enum wp_color_representation_surface_v1_coefficients coeffs = coefficients[i]; enum wlr_color_encoding enc = wlr_color_representation_v1_color_encoding_to_wlr(coeffs); diff --git a/types/wlr_cursor.c b/types/wlr_cursor.c index 8d0d77475..f2269db0f 100644 --- a/types/wlr_cursor.c +++ b/types/wlr_cursor.c @@ -956,7 +956,7 @@ static void handle_tablet_tool_axis(struct wl_listener *listener, void *data) { static void handle_tablet_tool_button(struct wl_listener *listener, void *data) { - struct wlr_tablet_tool_button_event *event = data; + struct wlr_tablet_tool_button *event = data; struct wlr_cursor_device *device; device = wl_container_of(listener, device, tablet_tool_button); wl_signal_emit_mutable(&device->cursor->events.tablet_tool_button, event); diff --git a/types/wlr_ext_image_copy_capture_v1.c b/types/wlr_ext_image_copy_capture_v1.c index 2e969b4a9..c9e7b0079 100644 --- a/types/wlr_ext_image_copy_capture_v1.c +++ b/types/wlr_ext_image_copy_capture_v1.c @@ -518,16 +518,14 @@ static void cursor_session_handle_get_capture_session(struct wl_client *client, return; } - struct wlr_ext_image_copy_capture_manager_v1 *manager = NULL; - struct wlr_ext_image_capture_source_v1 *source = NULL; + cursor_session->capture_session_created = true; + struct wlr_ext_image_capture_source_v1 *source = NULL; if (cursor_session != NULL) { - manager = cursor_session->manager; - cursor_session->capture_session_created = true; source = &cursor_session->source->base; } - session_create(cursor_session_resource, new_id, source, 0, manager); + session_create(cursor_session_resource, new_id, source, 0, cursor_session->manager); } static const struct ext_image_copy_capture_cursor_session_v1_interface cursor_session_impl = { diff --git a/types/wlr_keyboard_group.c b/types/wlr_keyboard_group.c index 6005ba647..0ff6d93bb 100644 --- a/types/wlr_keyboard_group.c +++ b/types/wlr_keyboard_group.c @@ -308,7 +308,7 @@ void wlr_keyboard_group_remove_keyboard(struct wlr_keyboard_group *group, void wlr_keyboard_group_destroy(struct wlr_keyboard_group *group) { struct keyboard_group_device *device, *tmp_device; wl_list_for_each_safe(device, tmp_device, &group->devices, link) { - remove_keyboard_group_device(device); + wlr_keyboard_group_remove_keyboard(group, device->keyboard); } // Now group->keys might not be empty if a wlr_keyboard has emitted diff --git a/types/wlr_linux_drm_syncobj_v1.c b/types/wlr_linux_drm_syncobj_v1.c index 53fc2fd43..988d44e01 100644 --- a/types/wlr_linux_drm_syncobj_v1.c +++ b/types/wlr_linux_drm_syncobj_v1.c @@ -3,7 +3,6 @@ #include #include #include -#include #include #include #include @@ -12,7 +11,6 @@ #include #include "config.h" #include "linux-drm-syncobj-v1-protocol.h" -#include "render/drm_syncobj_merger.h" #define LINUX_DRM_SYNCOBJ_V1_VERSION 1 @@ -160,39 +158,20 @@ static void surface_synced_finish_state(void *_state) { struct wlr_linux_drm_syncobj_surface_v1_state *state = _state; wlr_drm_syncobj_timeline_unref(state->acquire_timeline); wlr_drm_syncobj_timeline_unref(state->release_timeline); - wlr_drm_syncobj_merger_unref(state->release_merger); } static void surface_synced_move_state(void *_dst, void *_src) { struct wlr_linux_drm_syncobj_surface_v1_state *dst = _dst, *src = _src; - if (src->acquire_timeline == NULL) { - // ignore commits that did not attach a buffer - return; - } + // TODO: immediately signal dst.release_timeline if necessary surface_synced_finish_state(dst); *dst = *src; - dst->committed = true; *src = (struct wlr_linux_drm_syncobj_surface_v1_state){0}; } -static void surface_synced_commit(struct wlr_surface_synced *synced) { - struct wlr_linux_drm_syncobj_surface_v1 *surface = wl_container_of(synced, surface, synced); - - if (!surface->current.committed) { - return; - } - - surface->current.release_merger = wlr_drm_syncobj_merger_create( - surface->current.release_timeline, surface->current.release_point); - surface->current.committed = false; -} - - static const struct wlr_surface_synced_impl surface_synced_impl = { .state_size = sizeof(struct wlr_linux_drm_syncobj_surface_v1_state), .finish_state = surface_synced_finish_state, .move_state = surface_synced_move_state, - .commit = surface_synced_commit, }; static void manager_handle_destroy(struct wl_client *client, @@ -443,11 +422,6 @@ struct wlr_linux_drm_syncobj_manager_v1 *wlr_linux_drm_syncobj_manager_v1_create struct wl_display *display, uint32_t version, int drm_fd) { assert(version <= LINUX_DRM_SYNCOBJ_V1_VERSION); - if (!HAVE_LINUX_SYNC_FILE) { - wlr_log(WLR_INFO, "Linux sync_file unavailable, disabling linux-drm-syncobj-v1"); - return NULL; - } - if (!check_syncobj_eventfd(drm_fd)) { wlr_log(WLR_INFO, "DRM syncobj eventfd unavailable, disabling linux-drm-syncobj-v1"); return NULL; @@ -493,14 +467,20 @@ wlr_linux_drm_syncobj_v1_get_surface_state(struct wlr_surface *wlr_surface) { } struct release_signaller { - struct wlr_drm_syncobj_merger *merger; + struct wlr_drm_syncobj_timeline *timeline; + uint64_t point; struct wl_listener buffer_release; }; static void release_signaller_handle_buffer_release(struct wl_listener *listener, void *data) { struct release_signaller *signaller = wl_container_of(listener, signaller, buffer_release); - wlr_drm_syncobj_merger_unref(signaller->merger); + if (drmSyncobjTimelineSignal(signaller->timeline->drm_fd, &signaller->timeline->handle, + &signaller->point, 1) != 0) { + wlr_log(WLR_ERROR, "drmSyncobjTimelineSignal() failed"); + } + + wlr_drm_syncobj_timeline_unref(signaller->timeline); wl_list_remove(&signaller->buffer_release.link); free(signaller); } @@ -508,7 +488,7 @@ static void release_signaller_handle_buffer_release(struct wl_listener *listener bool wlr_linux_drm_syncobj_v1_state_signal_release_with_buffer( struct wlr_linux_drm_syncobj_surface_v1_state *state, struct wlr_buffer *buffer) { assert(buffer->n_locks > 0); - if (state->release_merger == NULL) { + if (state->release_timeline == NULL) { // This can happen if an existing surface with a buffer has a // syncobj_surface_v1_state created but no new buffer with release // timeline committed. @@ -520,23 +500,11 @@ bool wlr_linux_drm_syncobj_v1_state_signal_release_with_buffer( return false; } - signaller->merger = wlr_drm_syncobj_merger_ref(state->release_merger); + signaller->timeline = wlr_drm_syncobj_timeline_ref(state->release_timeline); + signaller->point = state->release_point; + signaller->buffer_release.notify = release_signaller_handle_buffer_release; wl_signal_add(&buffer->events.release, &signaller->buffer_release); return true; } - -bool wlr_linux_drm_syncobj_v1_state_add_release_point( - struct wlr_linux_drm_syncobj_surface_v1_state *state, - struct wlr_drm_syncobj_timeline *release_timeline, uint64_t release_point, - struct wl_event_loop *event_loop) { - if (state->release_merger == NULL) { - // This can happen if an existing surface with a buffer has a - // syncobj_surface_v1_state created but no new buffer with release - // timeline committed. - return true; - } - return wlr_drm_syncobj_merger_add(state->release_merger, - release_timeline, release_point, event_loop); -} diff --git a/types/wlr_output_layout.c b/types/wlr_output_layout.c index 7226809e7..ef2751179 100644 --- a/types/wlr_output_layout.c +++ b/types/wlr_output_layout.c @@ -260,12 +260,14 @@ bool wlr_output_layout_contains_point(struct wlr_output_layout *layout, bool wlr_output_layout_intersects(struct wlr_output_layout *layout, struct wlr_output *reference, const struct wlr_box *target_lbox) { + struct wlr_box out_box; + if (reference == NULL) { struct wlr_output_layout_output *l_output; wl_list_for_each(l_output, &layout->outputs, link) { struct wlr_box output_box; output_layout_output_get_box(l_output, &output_box); - if (wlr_box_intersects(&output_box, target_lbox)) { + if (wlr_box_intersection(&out_box, &output_box, target_lbox)) { return true; } } @@ -279,7 +281,7 @@ bool wlr_output_layout_intersects(struct wlr_output_layout *layout, struct wlr_box output_box; output_layout_output_get_box(l_output, &output_box); - return wlr_box_intersects(&output_box, target_lbox); + return wlr_box_intersection(&out_box, &output_box, target_lbox); } } diff --git a/types/wlr_screencopy_v1.c b/types/wlr_screencopy_v1.c index 9916a604c..58e8dc8ba 100644 --- a/types/wlr_screencopy_v1.c +++ b/types/wlr_screencopy_v1.c @@ -505,7 +505,7 @@ static void capture_output(struct wl_client *wl_client, wl_resource_set_implementation(frame->resource, &frame_impl, frame, frame_handle_resource_destroy); - if (output == NULL || !output->enabled) { + if (output == NULL) { wl_resource_set_user_data(frame->resource, NULL); zwlr_screencopy_frame_v1_send_failed(frame->resource); free(frame); @@ -522,6 +522,10 @@ static void capture_output(struct wl_client *wl_client, wl_signal_add(&output->events.destroy, &frame->output_destroy); frame->output_destroy.notify = frame_handle_output_destroy; + if (output == NULL || !output->enabled) { + goto error; + } + struct wlr_renderer *renderer = output->renderer; assert(renderer); diff --git a/types/wlr_virtual_keyboard_v1.c b/types/wlr_virtual_keyboard_v1.c index 011fbfec7..e7dcb3ec3 100644 --- a/types/wlr_virtual_keyboard_v1.c +++ b/types/wlr_virtual_keyboard_v1.c @@ -15,7 +15,7 @@ static const struct wlr_keyboard_impl keyboard_impl = { static const struct zwp_virtual_keyboard_v1_interface virtual_keyboard_impl; -struct wlr_virtual_keyboard_v1 *wlr_virtual_keyboard_v1_from_resource( +static struct wlr_virtual_keyboard_v1 *virtual_keyboard_from_resource( struct wl_resource *resource) { assert(wl_resource_instance_of(resource, &zwp_virtual_keyboard_v1_interface, &virtual_keyboard_impl)); @@ -39,7 +39,7 @@ static void virtual_keyboard_keymap(struct wl_client *client, struct wl_resource *resource, uint32_t format, int32_t fd, uint32_t size) { struct wlr_virtual_keyboard_v1 *keyboard = - wlr_virtual_keyboard_v1_from_resource(resource); + virtual_keyboard_from_resource(resource); if (keyboard == NULL) { return; } @@ -76,7 +76,7 @@ static void virtual_keyboard_key(struct wl_client *client, struct wl_resource *resource, uint32_t time, uint32_t key, uint32_t state) { struct wlr_virtual_keyboard_v1 *keyboard = - wlr_virtual_keyboard_v1_from_resource(resource); + virtual_keyboard_from_resource(resource); if (keyboard == NULL) { return; } @@ -99,7 +99,7 @@ static void virtual_keyboard_modifiers(struct wl_client *client, struct wl_resource *resource, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) { struct wlr_virtual_keyboard_v1 *keyboard = - wlr_virtual_keyboard_v1_from_resource(resource); + virtual_keyboard_from_resource(resource); if (keyboard == NULL) { return; } @@ -113,24 +113,21 @@ static void virtual_keyboard_modifiers(struct wl_client *client, mods_depressed, mods_latched, mods_locked, group); } -static void virtual_keyboard_destroy(struct wlr_virtual_keyboard_v1 *virtual_keyboard) { - wlr_keyboard_finish(&virtual_keyboard->keyboard); - wl_resource_set_user_data(virtual_keyboard->resource, NULL); - wl_list_remove(&virtual_keyboard->seat_destroy.link); - wl_list_remove(&virtual_keyboard->link); - free(virtual_keyboard); -} - static void virtual_keyboard_destroy_resource(struct wl_resource *resource) { - struct wlr_virtual_keyboard_v1 *virtual_keyboard = - wlr_virtual_keyboard_v1_from_resource(resource); - if (virtual_keyboard == NULL) { + struct wlr_virtual_keyboard_v1 *keyboard = + virtual_keyboard_from_resource(resource); + if (keyboard == NULL) { return; } - virtual_keyboard_destroy(virtual_keyboard); + + wlr_keyboard_finish(&keyboard->keyboard); + + wl_resource_set_user_data(keyboard->resource, NULL); + wl_list_remove(&keyboard->link); + free(keyboard); } -static void virtual_keyboard_handle_destroy(struct wl_client *client, +static void virtual_keyboard_destroy(struct wl_client *client, struct wl_resource *resource) { wl_resource_destroy(resource); } @@ -139,7 +136,7 @@ static const struct zwp_virtual_keyboard_v1_interface virtual_keyboard_impl = { .keymap = virtual_keyboard_keymap, .key = virtual_keyboard_key, .modifiers = virtual_keyboard_modifiers, - .destroy = virtual_keyboard_handle_destroy, + .destroy = virtual_keyboard_destroy, }; static const struct zwp_virtual_keyboard_manager_v1_interface manager_impl; @@ -151,13 +148,6 @@ static struct wlr_virtual_keyboard_manager_v1 *manager_from_resource( return wl_resource_get_user_data(resource); } -static void virtual_keyboard_handle_seat_destroy(struct wl_listener *listener, - void *data) { - struct wlr_virtual_keyboard_v1 *virtual_keyboard = wl_container_of(listener, virtual_keyboard, - seat_destroy); - virtual_keyboard_destroy(virtual_keyboard); -} - static void virtual_keyboard_manager_create_virtual_keyboard( struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat, uint32_t id) { @@ -191,9 +181,6 @@ static void virtual_keyboard_manager_create_virtual_keyboard( virtual_keyboard->seat = seat_client->seat; wl_resource_set_user_data(keyboard_resource, virtual_keyboard); - wl_signal_add(&seat_client->events.destroy, &virtual_keyboard->seat_destroy); - virtual_keyboard->seat_destroy.notify = virtual_keyboard_handle_seat_destroy; - wl_list_insert(&manager->virtual_keyboards, &virtual_keyboard->link); wl_signal_emit_mutable(&manager->events.new_virtual_keyboard, diff --git a/util/array.c b/util/array.c index d4771e817..ec16a7b13 100644 --- a/util/array.c +++ b/util/array.c @@ -14,7 +14,7 @@ bool array_realloc(struct wl_array *arr, size_t size) { // If the size is less than 1/4th of the allocation size, we shrink it. // 1/4th is picked to provide hysteresis, without which an array with size // arr->alloc would constantly reallocate if an element is added and then - // removed continuously. + // removed continously. size_t alloc; if (arr->alloc > 0 && size > arr->alloc / 4) { alloc = arr->alloc; diff --git a/util/box.c b/util/box.c index 62d405488..aae09888f 100644 --- a/util/box.c +++ b/util/box.c @@ -4,14 +4,6 @@ #include #include -static int max(int a, int b) { - return a > b ? a : b; -} - -static int min(int a, int b) { - return a < b ? a : b; -} - void wlr_box_closest_point(const struct wlr_box *box, double x, double y, double *dest_x, double *dest_y) { // if box is empty, then it contains no points, so no closest point either @@ -64,10 +56,10 @@ bool wlr_box_intersection(struct wlr_box *dest, const struct wlr_box *box_a, return false; } - int x1 = max(box_a->x, box_b->x); - int y1 = max(box_a->y, box_b->y); - int x2 = min(box_a->x + box_a->width, box_b->x + box_b->width); - int y2 = min(box_a->y + box_a->height, box_b->y + box_b->height); + int x1 = fmax(box_a->x, box_b->x); + int y1 = fmax(box_a->y, box_b->y); + int x2 = fmin(box_a->x + box_a->width, box_b->x + box_b->width); + int y2 = fmin(box_a->y + box_a->height, box_b->y + box_b->height); dest->x = x1; dest->y = y1; @@ -102,15 +94,6 @@ bool wlr_box_contains_box(const struct wlr_box *bigger, const struct wlr_box *sm smaller->y + smaller->height <= bigger->y + bigger->height; } -bool wlr_box_intersects(const struct wlr_box *a, const struct wlr_box *b) { - if (wlr_box_empty(a) || wlr_box_empty(b)) { - return false; - } - - return a->x < b->x + b->width && b->x < a->x + a->width && - a->y < b->y + b->height && b->y < a->y + a->height; -} - void wlr_box_transform(struct wlr_box *dest, const struct wlr_box *box, enum wl_output_transform transform, int width, int height) { struct wlr_box src = {0}; diff --git a/xwayland/selection/incoming.c b/xwayland/selection/incoming.c index 4fa851b2f..72f82c279 100644 --- a/xwayland/selection/incoming.c +++ b/xwayland/selection/incoming.c @@ -249,7 +249,7 @@ struct x11_data_source { static const struct wlr_data_source_impl data_source_impl; bool data_source_is_xwayland( - const struct wlr_data_source *wlr_source) { + struct wlr_data_source *wlr_source) { return wlr_source->impl == &data_source_impl; } @@ -292,7 +292,7 @@ static const struct wlr_primary_selection_source_impl primary_selection_source_impl; bool primary_selection_source_is_xwayland( - const struct wlr_primary_selection_source *wlr_source) { + struct wlr_primary_selection_source *wlr_source) { return wlr_source->impl == &primary_selection_source_impl; } @@ -381,15 +381,13 @@ static bool source_get_targets(struct wlr_xwm_selection *selection, free(mime_type); break; } + *mime_type_ptr = mime_type; xcb_atom_t *atom_ptr = wl_array_add(mime_types_atoms, sizeof(*atom_ptr)); if (atom_ptr == NULL) { - mime_types->size -= sizeof(*mime_type_ptr); - free(mime_type); break; } - *mime_type_ptr = mime_type; *atom_ptr = value[i]; } } diff --git a/xwayland/selection/outgoing.c b/xwayland/selection/outgoing.c index 6216abbb4..795a4768b 100644 --- a/xwayland/selection/outgoing.c +++ b/xwayland/selection/outgoing.c @@ -283,8 +283,6 @@ static bool xwm_selection_send_data(struct wlr_xwm_selection *selection, int p[2]; if (pipe(p) == -1) { wlr_log_errno(WLR_ERROR, "pipe() failed"); - wl_array_release(&transfer->source_data); - free(transfer); return false; } diff --git a/xwayland/xwm.c b/xwayland/xwm.c index e44a11743..c8eac2ce1 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -1,6 +1,5 @@ #include #include -#include #include #include #include @@ -2882,20 +2881,5 @@ xcb_connection_t *wlr_xwayland_get_xwm_connection( } void xwm_schedule_flush(struct wlr_xwm *xwm) { - struct pollfd pollfd = { - .fd = xcb_get_file_descriptor(xwm->xcb_conn), - .events = POLLOUT, - }; - if (poll(&pollfd, 1, 0) < 0) { - wlr_log(WLR_ERROR, "poll() failed"); - return; - } - - // If we can write immediately, do so - if (pollfd.revents & POLLOUT) { - xcb_flush(xwm->xcb_conn); - return; - } - wl_event_source_fd_update(xwm->event_source, WL_EVENT_READABLE | WL_EVENT_WRITABLE); }