aboutsummaryrefslogtreecommitdiff
path: root/sway
diff options
context:
space:
mode:
authorManuel Stoeckl <code@mstoeckl.com>2021-09-02 21:45:23 -0400
committerSimon Ser <contact@emersion.fr>2021-11-23 15:51:54 +0100
commita23cdbbea145e0890627743d316c0ab6fe6c9c1f (patch)
tree586a3c020872b9caa131ebc0ec1896043603f9c9 /sway
parent5865af75cf8029cc703cda36b68daafcb658c97b (diff)
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.
Diffstat (limited to 'sway')
-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
5 files changed, 84 insertions, 0 deletions
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[] = {
{ "modeline", output_cmd_modeline },
{ "pos", output_cmd_position },
{ "position", output_cmd_position },
+ { "render_bit_depth", output_cmd_render_bit_depth },
{ "res", output_cmd_mode },
{ "resolution", output_cmd_mode },
{ "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 @@
+#include <drm_fourcc.h>
+#include <strings.h>
+#include "sway/commands.h"
+#include "sway/config.h"
+
+struct cmd_results *output_cmd_render_bit_depth(int argc, char **argv) {
+ if (!config->handler_context.output_config) {
+ return cmd_results_new(CMD_FAILURE, "Missing output config");
+ }
+ if (!argc) {
+ return cmd_results_new(CMD_INVALID, "Missing bit depth argument.");
+ }
+
+ if (strcmp(*argv, "8") == 0) {
+ config->handler_context.output_config->render_bit_depth =
+ RENDER_BIT_DEPTH_8;
+ } else if (strcmp(*argv, "10") == 0) {
+ config->handler_context.output_config->render_bit_depth =
+ RENDER_BIT_DEPTH_10;
+ } else {
+ return cmd_results_new(CMD_INVALID,
+ "Invalid bit depth. Must be a value in (8|10).");
+ }
+
+ config->handler_context.leftovers.argc = argc - 1;
+ config->handler_context.leftovers.argv = argv + 1;
+ return NULL;
+}
+
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 @@
#define _POSIX_C_SOURCE 200809L
#include <assert.h>
+#include <drm_fourcc.h>
#include <stdbool.h>
#include <string.h>
#include <sys/socket.h>
@@ -67,6 +68,7 @@ struct output_config *new_output_config(const char *name) {
oc->subpixel = WL_OUTPUT_SUBPIXEL_UNKNOWN;
oc->max_render_time = -1;
oc->adaptive_sync = -1;
+ oc->render_bit_depth = RENDER_BIT_DEPTH_DEFAULT;
return oc;
}
@@ -113,6 +115,9 @@ void merge_output_config(struct output_config *dst, struct output_config *src) {
if (src->adaptive_sync != -1) {
dst->adaptive_sync = src->adaptive_sync;
}
+ if (src->render_bit_depth != RENDER_BIT_DEPTH_DEFAULT) {
+ dst->render_bit_depth = src->render_bit_depth;
+ }
if (src->background) {
free(dst->background);
dst->background = strdup(src->background);
@@ -351,6 +356,23 @@ static int compute_default_scale(struct wlr_output *output) {
return 2;
}
+/* Lists of formats to try, in order, when a specific render bit depth has
+ * been asked for. The second to last format in each list should always
+ * be XRGB8888, as a reliable backup in case the others are not available;
+ * the last should be DRM_FORMAT_INVALID, to indicate the end of the list. */
+static const uint32_t *bit_depth_preferences[] = {
+ [RENDER_BIT_DEPTH_8] = (const uint32_t []){
+ DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_INVALID,
+ },
+ [RENDER_BIT_DEPTH_10] = (const uint32_t []){
+ DRM_FORMAT_XRGB2101010,
+ DRM_FORMAT_XBGR2101010,
+ DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_INVALID,
+ },
+};
+
static void queue_output_config(struct output_config *oc,
struct sway_output *output) {
if (output == root->noop_output) {
@@ -437,6 +459,22 @@ static void queue_output_config(struct output_config *oc,
oc->adaptive_sync);
wlr_output_enable_adaptive_sync(wlr_output, oc->adaptive_sync == 1);
}
+
+ if (oc && oc->render_bit_depth != RENDER_BIT_DEPTH_DEFAULT) {
+ const uint32_t *fmts = bit_depth_preferences[oc->render_bit_depth];
+ assert(fmts);
+
+ for (size_t i = 0; fmts[i] != DRM_FORMAT_INVALID; i++) {
+ wlr_output_set_render_format(wlr_output, fmts[i]);
+ if (wlr_output_test(wlr_output)) {
+ break;
+ }
+
+ sway_log(SWAY_DEBUG, "Preferred output format 0x%08x "
+ "failed to work, falling back to next in "
+ "list, 0x%08x", fmts[i], fmts[i + 1]);
+ }
+ }
}
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(
'commands/output/max_render_time.c',
'commands/output/mode.c',
'commands/output/position.c',
+ 'commands/output/render_bit_depth.c',
'commands/output/scale.c',
'commands/output/scale_filter.c',
'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:
adaptive sync can improve latency, but can cause flickering on some
hardware.
+*output* <name> render_bit_depth 8|10
+ Controls the color channel bit depth at which frames are rendered; the
+ default is currently 8 bits per channel.
+
+ Setting higher values will not have an effect if hardware and software lack
+ support for such bit depths. Successfully increasing the render bit depth
+ will not necessarily increase the bit depth of the frames sent to a display.
+ An increased render bit depth may provide smoother rendering of gradients,
+ and screenshots which can more precisely store the colors of programs
+ which display high bit depth colors.
+
+ Warnings: this can break screenshot/screencast programs which have not been
+ updated to work with different bit depths. This command is experimental,
+ and may be removed or changed in the future.
+
# SEE ALSO
*sway*(5) *sway-input*(5)