diff options
-rw-r--r-- | include/sway/commands.h | 1 | ||||
-rw-r--r-- | include/sway/config.h | 7 | ||||
-rw-r--r-- | sway/commands/output.c | 1 | ||||
-rw-r--r-- | sway/commands/output/render_bit_depth.c | 29 | ||||
-rw-r--r-- | sway/config/output.c | 38 | ||||
-rw-r--r-- | sway/meson.build | 1 | ||||
-rw-r--r-- | sway/sway-output.5.scd | 15 |
7 files changed, 92 insertions, 0 deletions
diff --git a/include/sway/commands.h b/include/sway/commands.h index 4be40870..c6f5c2e0 100644 --- a/include/sway/commands.h +++ b/include/sway/commands.h | |||
@@ -284,6 +284,7 @@ sway_cmd output_cmd_max_render_time; | |||
284 | sway_cmd output_cmd_mode; | 284 | sway_cmd output_cmd_mode; |
285 | sway_cmd output_cmd_modeline; | 285 | sway_cmd output_cmd_modeline; |
286 | sway_cmd output_cmd_position; | 286 | sway_cmd output_cmd_position; |
287 | sway_cmd output_cmd_render_bit_depth; | ||
287 | sway_cmd output_cmd_scale; | 288 | sway_cmd output_cmd_scale; |
288 | sway_cmd output_cmd_scale_filter; | 289 | sway_cmd output_cmd_scale_filter; |
289 | sway_cmd output_cmd_subpixel; | 290 | sway_cmd output_cmd_subpixel; |
diff --git a/include/sway/config.h b/include/sway/config.h index 660245c1..aa71209d 100644 --- a/include/sway/config.h +++ b/include/sway/config.h | |||
@@ -247,6 +247,12 @@ enum scale_filter_mode { | |||
247 | SCALE_FILTER_SMART, | 247 | SCALE_FILTER_SMART, |
248 | }; | 248 | }; |
249 | 249 | ||
250 | enum render_bit_depth { | ||
251 | RENDER_BIT_DEPTH_DEFAULT, // the default is currently 8 | ||
252 | RENDER_BIT_DEPTH_8, | ||
253 | RENDER_BIT_DEPTH_10, | ||
254 | }; | ||
255 | |||
250 | /** | 256 | /** |
251 | * Size and position configuration for a particular output. | 257 | * Size and position configuration for a particular output. |
252 | * | 258 | * |
@@ -266,6 +272,7 @@ struct output_config { | |||
266 | enum wl_output_subpixel subpixel; | 272 | enum wl_output_subpixel subpixel; |
267 | int max_render_time; // In milliseconds | 273 | int max_render_time; // In milliseconds |
268 | int adaptive_sync; | 274 | int adaptive_sync; |
275 | enum render_bit_depth render_bit_depth; | ||
269 | 276 | ||
270 | char *background; | 277 | char *background; |
271 | char *background_option; | 278 | char *background_option; |
diff --git a/sway/commands/output.c b/sway/commands/output.c index d8ef2885..42230bd7 100644 --- a/sway/commands/output.c +++ b/sway/commands/output.c | |||
@@ -18,6 +18,7 @@ static const struct cmd_handler output_handlers[] = { | |||
18 | { "modeline", output_cmd_modeline }, | 18 | { "modeline", output_cmd_modeline }, |
19 | { "pos", output_cmd_position }, | 19 | { "pos", output_cmd_position }, |
20 | { "position", output_cmd_position }, | 20 | { "position", output_cmd_position }, |
21 | { "render_bit_depth", output_cmd_render_bit_depth }, | ||
21 | { "res", output_cmd_mode }, | 22 | { "res", output_cmd_mode }, |
22 | { "resolution", output_cmd_mode }, | 23 | { "resolution", output_cmd_mode }, |
23 | { "scale", output_cmd_scale }, | 24 | { "scale", output_cmd_scale }, |
diff --git a/sway/commands/output/render_bit_depth.c b/sway/commands/output/render_bit_depth.c new file mode 100644 index 00000000..c419321e --- /dev/null +++ b/sway/commands/output/render_bit_depth.c | |||
@@ -0,0 +1,29 @@ | |||
1 | #include <drm_fourcc.h> | ||
2 | #include <strings.h> | ||
3 | #include "sway/commands.h" | ||
4 | #include "sway/config.h" | ||
5 | |||
6 | struct cmd_results *output_cmd_render_bit_depth(int argc, char **argv) { | ||
7 | if (!config->handler_context.output_config) { | ||
8 | return cmd_results_new(CMD_FAILURE, "Missing output config"); | ||
9 | } | ||
10 | if (!argc) { | ||
11 | return cmd_results_new(CMD_INVALID, "Missing bit depth argument."); | ||
12 | } | ||
13 | |||
14 | if (strcmp(*argv, "8") == 0) { | ||
15 | config->handler_context.output_config->render_bit_depth = | ||
16 | RENDER_BIT_DEPTH_8; | ||
17 | } else if (strcmp(*argv, "10") == 0) { | ||
18 | config->handler_context.output_config->render_bit_depth = | ||
19 | RENDER_BIT_DEPTH_10; | ||
20 | } else { | ||
21 | return cmd_results_new(CMD_INVALID, | ||
22 | "Invalid bit depth. Must be a value in (8|10)."); | ||
23 | } | ||
24 | |||
25 | config->handler_context.leftovers.argc = argc - 1; | ||
26 | config->handler_context.leftovers.argv = argv + 1; | ||
27 | return NULL; | ||
28 | } | ||
29 | |||
diff --git a/sway/config/output.c b/sway/config/output.c index 6d39c2f5..63c81382 100644 --- a/sway/config/output.c +++ b/sway/config/output.c | |||
@@ -1,5 +1,6 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | 1 | #define _POSIX_C_SOURCE 200809L |
2 | #include <assert.h> | 2 | #include <assert.h> |
3 | #include <drm_fourcc.h> | ||
3 | #include <stdbool.h> | 4 | #include <stdbool.h> |
4 | #include <string.h> | 5 | #include <string.h> |
5 | #include <sys/socket.h> | 6 | #include <sys/socket.h> |
@@ -67,6 +68,7 @@ struct output_config *new_output_config(const char *name) { | |||
67 | oc->subpixel = WL_OUTPUT_SUBPIXEL_UNKNOWN; | 68 | oc->subpixel = WL_OUTPUT_SUBPIXEL_UNKNOWN; |
68 | oc->max_render_time = -1; | 69 | oc->max_render_time = -1; |
69 | oc->adaptive_sync = -1; | 70 | oc->adaptive_sync = -1; |
71 | oc->render_bit_depth = RENDER_BIT_DEPTH_DEFAULT; | ||
70 | return oc; | 72 | return oc; |
71 | } | 73 | } |
72 | 74 | ||
@@ -113,6 +115,9 @@ void merge_output_config(struct output_config *dst, struct output_config *src) { | |||
113 | if (src->adaptive_sync != -1) { | 115 | if (src->adaptive_sync != -1) { |
114 | dst->adaptive_sync = src->adaptive_sync; | 116 | dst->adaptive_sync = src->adaptive_sync; |
115 | } | 117 | } |
118 | if (src->render_bit_depth != RENDER_BIT_DEPTH_DEFAULT) { | ||
119 | dst->render_bit_depth = src->render_bit_depth; | ||
120 | } | ||
116 | if (src->background) { | 121 | if (src->background) { |
117 | free(dst->background); | 122 | free(dst->background); |
118 | dst->background = strdup(src->background); | 123 | dst->background = strdup(src->background); |
@@ -351,6 +356,23 @@ static int compute_default_scale(struct wlr_output *output) { | |||
351 | return 2; | 356 | return 2; |
352 | } | 357 | } |
353 | 358 | ||
359 | /* Lists of formats to try, in order, when a specific render bit depth has | ||
360 | * been asked for. The second to last format in each list should always | ||
361 | * be XRGB8888, as a reliable backup in case the others are not available; | ||
362 | * the last should be DRM_FORMAT_INVALID, to indicate the end of the list. */ | ||
363 | static const uint32_t *bit_depth_preferences[] = { | ||
364 | [RENDER_BIT_DEPTH_8] = (const uint32_t []){ | ||
365 | DRM_FORMAT_XRGB8888, | ||
366 | DRM_FORMAT_INVALID, | ||
367 | }, | ||
368 | [RENDER_BIT_DEPTH_10] = (const uint32_t []){ | ||
369 | DRM_FORMAT_XRGB2101010, | ||
370 | DRM_FORMAT_XBGR2101010, | ||
371 | DRM_FORMAT_XRGB8888, | ||
372 | DRM_FORMAT_INVALID, | ||
373 | }, | ||
374 | }; | ||
375 | |||
354 | static void queue_output_config(struct output_config *oc, | 376 | static void queue_output_config(struct output_config *oc, |
355 | struct sway_output *output) { | 377 | struct sway_output *output) { |
356 | if (output == root->noop_output) { | 378 | if (output == root->noop_output) { |
@@ -437,6 +459,22 @@ static void queue_output_config(struct output_config *oc, | |||
437 | oc->adaptive_sync); | 459 | oc->adaptive_sync); |
438 | wlr_output_enable_adaptive_sync(wlr_output, oc->adaptive_sync == 1); | 460 | wlr_output_enable_adaptive_sync(wlr_output, oc->adaptive_sync == 1); |
439 | } | 461 | } |
462 | |||
463 | if (oc && oc->render_bit_depth != RENDER_BIT_DEPTH_DEFAULT) { | ||
464 | const uint32_t *fmts = bit_depth_preferences[oc->render_bit_depth]; | ||
465 | assert(fmts); | ||
466 | |||
467 | for (size_t i = 0; fmts[i] != DRM_FORMAT_INVALID; i++) { | ||
468 | wlr_output_set_render_format(wlr_output, fmts[i]); | ||
469 | if (wlr_output_test(wlr_output)) { | ||
470 | break; | ||
471 | } | ||
472 | |||
473 | sway_log(SWAY_DEBUG, "Preferred output format 0x%08x " | ||
474 | "failed to work, falling back to next in " | ||
475 | "list, 0x%08x", fmts[i], fmts[i + 1]); | ||
476 | } | ||
477 | } | ||
440 | } | 478 | } |
441 | 479 | ||
442 | bool apply_output_config(struct output_config *oc, struct sway_output *output) { | 480 | bool apply_output_config(struct output_config *oc, struct sway_output *output) { |
diff --git a/sway/meson.build b/sway/meson.build index 1402db15..8eab31a2 100644 --- a/sway/meson.build +++ b/sway/meson.build | |||
@@ -188,6 +188,7 @@ sway_sources = files( | |||
188 | 'commands/output/max_render_time.c', | 188 | 'commands/output/max_render_time.c', |
189 | 'commands/output/mode.c', | 189 | 'commands/output/mode.c', |
190 | 'commands/output/position.c', | 190 | 'commands/output/position.c', |
191 | 'commands/output/render_bit_depth.c', | ||
191 | 'commands/output/scale.c', | 192 | 'commands/output/scale.c', |
192 | 'commands/output/scale_filter.c', | 193 | 'commands/output/scale_filter.c', |
193 | 'commands/output/subpixel.c', | 194 | 'commands/output/subpixel.c', |
diff --git a/sway/sway-output.5.scd b/sway/sway-output.5.scd index 55d8f719..4159a851 100644 --- a/sway/sway-output.5.scd +++ b/sway/sway-output.5.scd | |||
@@ -157,6 +157,21 @@ must be separated by one space. For example: | |||
157 | adaptive sync can improve latency, but can cause flickering on some | 157 | adaptive sync can improve latency, but can cause flickering on some |
158 | hardware. | 158 | hardware. |
159 | 159 | ||
160 | *output* <name> render_bit_depth 8|10 | ||
161 | Controls the color channel bit depth at which frames are rendered; the | ||
162 | default is currently 8 bits per channel. | ||
163 | |||
164 | Setting higher values will not have an effect if hardware and software lack | ||
165 | support for such bit depths. Successfully increasing the render bit depth | ||
166 | will not necessarily increase the bit depth of the frames sent to a display. | ||
167 | An increased render bit depth may provide smoother rendering of gradients, | ||
168 | and screenshots which can more precisely store the colors of programs | ||
169 | which display high bit depth colors. | ||
170 | |||
171 | Warnings: this can break screenshot/screencast programs which have not been | ||
172 | updated to work with different bit depths. This command is experimental, | ||
173 | and may be removed or changed in the future. | ||
174 | |||
160 | # SEE ALSO | 175 | # SEE ALSO |
161 | 176 | ||
162 | *sway*(5) *sway-input*(5) | 177 | *sway*(5) *sway-input*(5) |