aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsaac Freund <mail@isaacfreund.com>2022-07-06 17:47:19 +0200
committerSimon Ser <contact@emersion.fr>2022-10-24 16:19:25 +0000
commita773231c42812e56c5966fc6a035aa9c6108175a (patch)
treec49efe72c903ed6e2f3f4a7b63f72f92061886e4
parentc2d2773df57750081b16d56da13b5015d752cbd7 (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.h1
-rw-r--r--protocol/wlr-output-management-unstable-v1.xml36
-rw-r--r--types/wlr_output_management_v1.c49
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);
}