diff options
author | Isaac Freund <mail@isaacfreund.com> | 2022-07-06 17:47:19 +0200 |
---|---|---|
committer | Simon Ser <contact@emersion.fr> | 2022-10-24 16:19:25 +0000 |
commit | a773231c42812e56c5966fc6a035aa9c6108175a (patch) | |
tree | c49efe72c903ed6e2f3f4a7b63f72f92061886e4 | |
parent | c2d2773df57750081b16d56da13b5015d752cbd7 (diff) |
wlr-output-management: implement adaptive sync
Version 4 of the protocol adds support for reporting/setting adaptive
sync state of outputs. Implement these new requests/events in wlroots.
-rw-r--r-- | include/wlr/types/wlr_output_management_v1.h | 1 | ||||
-rw-r--r-- | protocol/wlr-output-management-unstable-v1.xml | 36 | ||||
-rw-r--r-- | types/wlr_output_management_v1.c | 49 |
3 files changed, 80 insertions, 6 deletions
diff --git a/include/wlr/types/wlr_output_management_v1.h b/include/wlr/types/wlr_output_management_v1.h index be56e812..f1cd5ec5 100644 --- a/include/wlr/types/wlr_output_management_v1.h +++ b/include/wlr/types/wlr_output_management_v1.h @@ -56,6 +56,7 @@ struct wlr_output_head_v1_state { int32_t x, y; enum wl_output_transform transform; float scale; + bool adaptive_sync_enabled; }; struct wlr_output_head_v1 { diff --git a/protocol/wlr-output-management-unstable-v1.xml b/protocol/wlr-output-management-unstable-v1.xml index 3568e04c..411e2f04 100644 --- a/protocol/wlr-output-management-unstable-v1.xml +++ b/protocol/wlr-output-management-unstable-v1.xml @@ -39,7 +39,7 @@ interface version number is reset. </description> - <interface name="zwlr_output_manager_v1" version="3"> + <interface name="zwlr_output_manager_v1" version="4"> <description summary="output device configuration manager"> This interface is a manager that allows reading and writing the current output device configuration. @@ -125,7 +125,7 @@ </event> </interface> - <interface name="zwlr_output_head_v1" version="3"> + <interface name="zwlr_output_head_v1" version="4"> <description summary="output device"> A head is an output device. The difference between a wl_output object and a head is that heads are advertised even if they are turned off. A head @@ -338,6 +338,22 @@ object. </description> </request> + + <!-- Version 4 additions --> + + <enum name="adaptive_sync_state" since="4"> + <entry name="disabled" value="0" summary="adaptive sync is disabled"/> + <entry name="enabled" value="1" summary="adaptive sync is enabled"/> + </enum> + + <event name="adaptive_sync" since="4"> + <description summary="current adaptive sync state"> + This event describes whether adaptive sync is currently enabled for + the head or not. Adaptive sync is also known as Variable Refresh + Rate or VRR. + </description> + <arg name="state" type="uint" enum="adaptive_sync_state"/> + </event> </interface> <interface name="zwlr_output_mode_v1" version="3"> @@ -395,7 +411,7 @@ </request> </interface> - <interface name="zwlr_output_configuration_v1" version="3"> + <interface name="zwlr_output_configuration_v1" version="4"> <description summary="output configuration"> This object is used by the client to describe a full output configuration. @@ -513,7 +529,7 @@ </request> </interface> - <interface name="zwlr_output_configuration_head_v1" version="3"> + <interface name="zwlr_output_configuration_head_v1" version="4"> <description summary="head configuration"> This object is used by the client to update a single head's configuration. @@ -526,6 +542,8 @@ <entry name="invalid_custom_mode" value="3" summary="mode is invalid"/> <entry name="invalid_transform" value="4" summary="transform value outside enum"/> <entry name="invalid_scale" value="5" summary="scale negative or zero"/> + <entry name="invalid_adaptive_sync_state" value="6" since="4" + summary="invalid enum value used in the set_adaptive_sync request"/> </enum> <request name="set_mode"> @@ -569,5 +587,15 @@ </description> <arg name="scale" type="fixed"/> </request> + + <!-- Version 4 additions --> + + <request name="set_adaptive_sync" since="4"> + <description summary="enable/disable adaptive sync"> + This request enables/disables adaptive sync. Adaptive sync is also + known as Variable Refresh Rate or VRR. + </description> + <arg name="state" type="uint" enum="zwlr_output_head_v1.adaptive_sync_state"/> + </request> </interface> </protocol> diff --git a/types/wlr_output_management_v1.c b/types/wlr_output_management_v1.c index 3fb9cf43..b6dfb93d 100644 --- a/types/wlr_output_management_v1.c +++ b/types/wlr_output_management_v1.c @@ -5,7 +5,7 @@ #include <wlr/util/log.h> #include "wlr-output-management-unstable-v1-protocol.h" -#define OUTPUT_MANAGER_VERSION 3 +#define OUTPUT_MANAGER_VERSION 4 enum { HEAD_STATE_ENABLED = 1 << 0, @@ -13,10 +13,12 @@ enum { HEAD_STATE_POSITION = 1 << 2, HEAD_STATE_TRANSFORM = 1 << 3, HEAD_STATE_SCALE = 1 << 4, + HEAD_STATE_ADAPTIVE_SYNC = 1 << 5, }; static const uint32_t HEAD_STATE_ALL = HEAD_STATE_ENABLED | HEAD_STATE_MODE | - HEAD_STATE_POSITION | HEAD_STATE_TRANSFORM | HEAD_STATE_SCALE; + HEAD_STATE_POSITION | HEAD_STATE_TRANSFORM | HEAD_STATE_SCALE | + HEAD_STATE_ADAPTIVE_SYNC; static const struct zwlr_output_head_v1_interface head_impl; @@ -135,6 +137,8 @@ struct wlr_output_configuration_head_v1 * config_head->state.custom_mode.refresh = output->refresh; config_head->state.transform = output->transform; config_head->state.scale = output->scale; + config_head->state.adaptive_sync_enabled = + output->adaptive_sync_status == WLR_OUTPUT_ADAPTIVE_SYNC_ENABLED; return config_head; } @@ -258,12 +262,36 @@ static void config_head_handle_set_scale(struct wl_client *client, config_head->state.scale = scale; } +static void config_head_handle_set_adaptive_sync(struct wl_client *client, + struct wl_resource *config_head_resource, uint32_t state) { + struct wlr_output_configuration_head_v1 *config_head = + config_head_from_resource(config_head_resource); + if (config_head == NULL) { + return; + } + + switch (state) { + case ZWLR_OUTPUT_HEAD_V1_ADAPTIVE_SYNC_STATE_ENABLED: + config_head->state.adaptive_sync_enabled = true; + break; + case ZWLR_OUTPUT_HEAD_V1_ADAPTIVE_SYNC_STATE_DISABLED: + config_head->state.adaptive_sync_enabled = false; + break; + default: + wl_resource_post_error(config_head_resource, + ZWLR_OUTPUT_CONFIGURATION_HEAD_V1_ERROR_INVALID_ADAPTIVE_SYNC_STATE, + "client requested invalid adaptive sync state %ul", state); + break; + } +} + static const struct zwlr_output_configuration_head_v1_interface config_head_impl = { .set_mode = config_head_handle_set_mode, .set_custom_mode = config_head_handle_set_custom_mode, .set_position = config_head_handle_set_position, .set_transform = config_head_handle_set_transform, .set_scale = config_head_handle_set_scale, + .set_adaptive_sync = config_head_handle_set_adaptive_sync, }; static void config_head_handle_resource_destroy(struct wl_resource *resource) { @@ -750,6 +778,18 @@ static void head_send_state(struct wlr_output_head_v1 *head, zwlr_output_head_v1_send_scale(head_resource, wl_fixed_from_double(head->state.scale)); } + + if ((state & HEAD_STATE_ADAPTIVE_SYNC) && + wl_resource_get_version(head_resource) >= + ZWLR_OUTPUT_HEAD_V1_ADAPTIVE_SYNC_SINCE_VERSION) { + if (head->state.adaptive_sync_enabled) { + zwlr_output_head_v1_send_adaptive_sync(head_resource, + ZWLR_OUTPUT_HEAD_V1_ADAPTIVE_SYNC_STATE_ENABLED); + } else { + zwlr_output_head_v1_send_adaptive_sync(head_resource, + ZWLR_OUTPUT_HEAD_V1_ADAPTIVE_SYNC_STATE_DISABLED); + } + } } static void head_handle_resource_destroy(struct wl_resource *resource) { @@ -843,6 +883,9 @@ static bool manager_update_head(struct wlr_output_manager_v1 *manager, if (current->scale != next->scale) { state |= HEAD_STATE_SCALE; } + if (current->adaptive_sync_enabled != next->adaptive_sync_enabled) { + state |= HEAD_STATE_ADAPTIVE_SYNC; + } // If a mode was added to wlr_output.modes we need to add the new mode // to the wlr_output_head @@ -953,4 +996,6 @@ void wlr_output_head_v1_state_apply( wlr_output_state_set_scale(output_state, head_state->scale); wlr_output_state_set_transform(output_state, head_state->transform); + wlr_output_state_set_adaptive_sync_enabled(output_state, + head_state->adaptive_sync_enabled); } |