aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Manuel Stoeckl <code@mstoeckl.com>2021-09-02 21:45:23 -0400
committerLibravatar Simon Ser <contact@emersion.fr>2021-11-23 15:51:54 +0100
commita23cdbbea145e0890627743d316c0ab6fe6c9c1f (patch)
tree586a3c020872b9caa131ebc0ec1896043603f9c9
parentsway: create wlr_renderer and wlr_allocator (diff)
downloadsway-a23cdbbea145e0890627743d316c0ab6fe6c9c1f.tar.gz
sway-a23cdbbea145e0890627743d316c0ab6fe6c9c1f.tar.zst
sway-a23cdbbea145e0890627743d316c0ab6fe6c9c1f.zip
Add 'output render_bit_depth [8|10]' command
This makes it possible to hint to the renderer and backends how many bits per channel the buffers that the compositor draws windows onto should have. Renderers and backends may deviate from this if they do not support the formats with higher bit depth.
-rw-r--r--include/sway/commands.h1
-rw-r--r--include/sway/config.h7
-rw-r--r--sway/commands/output.c1
-rw-r--r--sway/commands/output/render_bit_depth.c29
-rw-r--r--sway/config/output.c38
-rw-r--r--sway/meson.build1
-rw-r--r--sway/sway-output.5.scd15
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;
284sway_cmd output_cmd_mode; 284sway_cmd output_cmd_mode;
285sway_cmd output_cmd_modeline; 285sway_cmd output_cmd_modeline;
286sway_cmd output_cmd_position; 286sway_cmd output_cmd_position;
287sway_cmd output_cmd_render_bit_depth;
287sway_cmd output_cmd_scale; 288sway_cmd output_cmd_scale;
288sway_cmd output_cmd_scale_filter; 289sway_cmd output_cmd_scale_filter;
289sway_cmd output_cmd_subpixel; 290sway_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
250enum 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
6struct 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. */
363static 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
354static void queue_output_config(struct output_config *oc, 376static 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
442bool apply_output_config(struct output_config *oc, struct sway_output *output) { 480bool 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)