mirror of
https://github.com/swaywm/sway.git
synced 2025-10-29 05:40:18 -04:00
Add support for HDR10 output
This commit is contained in:
parent
c7d7d56f61
commit
bac8c0f4d0
11 changed files with 139 additions and 23 deletions
|
|
@ -290,6 +290,7 @@ sway_cmd output_cmd_color_profile;
|
||||||
sway_cmd output_cmd_disable;
|
sway_cmd output_cmd_disable;
|
||||||
sway_cmd output_cmd_dpms;
|
sway_cmd output_cmd_dpms;
|
||||||
sway_cmd output_cmd_enable;
|
sway_cmd output_cmd_enable;
|
||||||
|
sway_cmd output_cmd_hdr;
|
||||||
sway_cmd output_cmd_max_render_time;
|
sway_cmd output_cmd_max_render_time;
|
||||||
sway_cmd output_cmd_mode;
|
sway_cmd output_cmd_mode;
|
||||||
sway_cmd output_cmd_modeline;
|
sway_cmd output_cmd_modeline;
|
||||||
|
|
|
||||||
|
|
@ -261,7 +261,7 @@ enum scale_filter_mode {
|
||||||
};
|
};
|
||||||
|
|
||||||
enum render_bit_depth {
|
enum render_bit_depth {
|
||||||
RENDER_BIT_DEPTH_DEFAULT, // the default is currently 8
|
RENDER_BIT_DEPTH_DEFAULT, // the default is currently 8 for SDR, 10 for HDR
|
||||||
RENDER_BIT_DEPTH_6,
|
RENDER_BIT_DEPTH_6,
|
||||||
RENDER_BIT_DEPTH_8,
|
RENDER_BIT_DEPTH_8,
|
||||||
RENDER_BIT_DEPTH_10,
|
RENDER_BIT_DEPTH_10,
|
||||||
|
|
@ -291,6 +291,7 @@ struct output_config {
|
||||||
bool set_color_transform;
|
bool set_color_transform;
|
||||||
struct wlr_color_transform *color_transform;
|
struct wlr_color_transform *color_transform;
|
||||||
int allow_tearing;
|
int allow_tearing;
|
||||||
|
int hdr;
|
||||||
|
|
||||||
char *background;
|
char *background;
|
||||||
char *background_option;
|
char *background_option;
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,9 @@ struct sway_output {
|
||||||
uint32_t refresh_nsec;
|
uint32_t refresh_nsec;
|
||||||
int max_render_time; // In milliseconds
|
int max_render_time; // In milliseconds
|
||||||
struct wl_event_source *repaint_timer;
|
struct wl_event_source *repaint_timer;
|
||||||
|
|
||||||
bool allow_tearing;
|
bool allow_tearing;
|
||||||
|
bool hdr;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sway_output_non_desktop {
|
struct sway_output_non_desktop {
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ static const struct cmd_handler output_handlers[] = {
|
||||||
{ "disable", output_cmd_disable },
|
{ "disable", output_cmd_disable },
|
||||||
{ "dpms", output_cmd_dpms },
|
{ "dpms", output_cmd_dpms },
|
||||||
{ "enable", output_cmd_enable },
|
{ "enable", output_cmd_enable },
|
||||||
|
{ "hdr", output_cmd_hdr },
|
||||||
{ "max_render_time", output_cmd_max_render_time },
|
{ "max_render_time", output_cmd_max_render_time },
|
||||||
{ "mode", output_cmd_mode },
|
{ "mode", output_cmd_mode },
|
||||||
{ "modeline", output_cmd_modeline },
|
{ "modeline", output_cmd_modeline },
|
||||||
|
|
|
||||||
37
sway/commands/output/hdr.c
Normal file
37
sway/commands/output/hdr.c
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
#include <strings.h>
|
||||||
|
#include "sway/commands.h"
|
||||||
|
#include "sway/config.h"
|
||||||
|
#include "sway/output.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
struct cmd_results *output_cmd_hdr(int argc, char **argv) {
|
||||||
|
if (!config->handler_context.output_config) {
|
||||||
|
return cmd_results_new(CMD_FAILURE, "Missing output config");
|
||||||
|
}
|
||||||
|
if (argc == 0) {
|
||||||
|
return cmd_results_new(CMD_INVALID, "Missing hdr argument");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool current = false;
|
||||||
|
if (strcasecmp(argv[0], "toggle") == 0) {
|
||||||
|
const char *oc_name = config->handler_context.output_config->name;
|
||||||
|
if (strcmp(oc_name, "*") == 0) {
|
||||||
|
return cmd_results_new(CMD_INVALID,
|
||||||
|
"Cannot apply toggle to all outputs");
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sway_output *output = all_output_by_name_or_id(oc_name);
|
||||||
|
if (!output) {
|
||||||
|
return cmd_results_new(CMD_FAILURE,
|
||||||
|
"Cannot apply toggle to unknown output %s", oc_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
current = output->hdr;
|
||||||
|
}
|
||||||
|
|
||||||
|
config->handler_context.output_config->hdr = parse_boolean(argv[0], current);
|
||||||
|
|
||||||
|
config->handler_context.leftovers.argc = argc - 1;
|
||||||
|
config->handler_context.leftovers.argv = argv + 1;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
@ -79,6 +79,7 @@ struct output_config *new_output_config(const char *name) {
|
||||||
oc->color_transform = NULL;
|
oc->color_transform = NULL;
|
||||||
oc->power = -1;
|
oc->power = -1;
|
||||||
oc->allow_tearing = -1;
|
oc->allow_tearing = -1;
|
||||||
|
oc->hdr = -1;
|
||||||
return oc;
|
return oc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -154,6 +155,9 @@ static void supersede_output_config(struct output_config *dst, struct output_con
|
||||||
if (src->allow_tearing != -1) {
|
if (src->allow_tearing != -1) {
|
||||||
dst->allow_tearing = -1;
|
dst->allow_tearing = -1;
|
||||||
}
|
}
|
||||||
|
if (src->hdr != -1) {
|
||||||
|
dst->hdr = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// merge_output_config sets all fields in dst that were set in src
|
// merge_output_config sets all fields in dst that were set in src
|
||||||
|
|
@ -229,6 +233,9 @@ static void merge_output_config(struct output_config *dst, struct output_config
|
||||||
if (src->allow_tearing != -1) {
|
if (src->allow_tearing != -1) {
|
||||||
dst->allow_tearing = src->allow_tearing;
|
dst->allow_tearing = src->allow_tearing;
|
||||||
}
|
}
|
||||||
|
if (src->hdr != -1) {
|
||||||
|
dst->hdr = src->hdr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void store_output_config(struct output_config *oc) {
|
void store_output_config(struct output_config *oc) {
|
||||||
|
|
@ -271,11 +278,11 @@ void store_output_config(struct output_config *oc) {
|
||||||
|
|
||||||
sway_log(SWAY_DEBUG, "Config stored for output %s (enabled: %d) (%dx%d@%fHz "
|
sway_log(SWAY_DEBUG, "Config stored for output %s (enabled: %d) (%dx%d@%fHz "
|
||||||
"position %d,%d scale %f subpixel %s transform %d) (bg %s %s) (power %d) "
|
"position %d,%d scale %f subpixel %s transform %d) (bg %s %s) (power %d) "
|
||||||
"(max render time: %d) (allow tearing: %d)",
|
"(max render time: %d) (allow tearing: %d) (hdr: %d)",
|
||||||
oc->name, oc->enabled, oc->width, oc->height, oc->refresh_rate,
|
oc->name, oc->enabled, oc->width, oc->height, oc->refresh_rate,
|
||||||
oc->x, oc->y, oc->scale, sway_wl_output_subpixel_to_string(oc->subpixel),
|
oc->x, oc->y, oc->scale, sway_wl_output_subpixel_to_string(oc->subpixel),
|
||||||
oc->transform, oc->background, oc->background_option, oc->power,
|
oc->transform, oc->background, oc->background_option, oc->power,
|
||||||
oc->max_render_time, oc->allow_tearing);
|
oc->max_render_time, oc->allow_tearing, oc->hdr);
|
||||||
|
|
||||||
// If the configuration was not merged into an existing configuration, add
|
// If the configuration was not merged into an existing configuration, add
|
||||||
// it to the list. Otherwise we're done with it and can free it.
|
// it to the list. Otherwise we're done with it and can free it.
|
||||||
|
|
@ -341,6 +348,41 @@ static void set_modeline(struct wlr_output *output,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void set_hdr(struct wlr_output *output, struct wlr_output_state *pending, bool enabled) {
|
||||||
|
enum wlr_color_named_primaries primaries = WLR_COLOR_NAMED_PRIMARIES_BT2020;
|
||||||
|
enum wlr_color_transfer_function tf = WLR_COLOR_TRANSFER_FUNCTION_ST2084_PQ;
|
||||||
|
if (enabled && !(output->supported_primaries & primaries)) {
|
||||||
|
sway_log(SWAY_ERROR, "Cannot enable HDR on output %s: BT2020 primaries not supported by output",
|
||||||
|
output->name);
|
||||||
|
enabled = false;
|
||||||
|
}
|
||||||
|
if (enabled && !(output->supported_transfer_functions & WLR_COLOR_TRANSFER_FUNCTION_ST2084_PQ)) {
|
||||||
|
sway_log(SWAY_ERROR, "Cannot enable HDR on output %s: PQ transfer function not supported by output",
|
||||||
|
output->name);
|
||||||
|
enabled = false;
|
||||||
|
}
|
||||||
|
if (enabled && !server.renderer->features.output_color_transform) {
|
||||||
|
sway_log(SWAY_ERROR, "Cannot enable HDR on output %s: renderer doesn't support output color transforms",
|
||||||
|
output->name);
|
||||||
|
enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!enabled) {
|
||||||
|
if (output->supported_primaries != 0 || output->supported_transfer_functions != 0) {
|
||||||
|
sway_log(SWAY_DEBUG, "Disabling HDR on output %s", output->name);
|
||||||
|
wlr_output_state_set_image_description(pending, NULL);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sway_log(SWAY_DEBUG, "Enabling HDR on output %s", output->name);
|
||||||
|
const struct wlr_output_image_description image_desc = {
|
||||||
|
.primaries = primaries,
|
||||||
|
.transfer_function = tf,
|
||||||
|
};
|
||||||
|
wlr_output_state_set_image_description(pending, &image_desc);
|
||||||
|
}
|
||||||
|
|
||||||
/* Some manufacturers hardcode the aspect-ratio of the output in the physical
|
/* Some manufacturers hardcode the aspect-ratio of the output in the physical
|
||||||
* size field. */
|
* size field. */
|
||||||
static bool phys_size_is_aspect_ratio(struct wlr_output *output) {
|
static bool phys_size_is_aspect_ratio(struct wlr_output *output) {
|
||||||
|
|
@ -415,6 +457,16 @@ static enum render_bit_depth bit_depth_from_format(uint32_t render_format) {
|
||||||
return RENDER_BIT_DEPTH_DEFAULT;
|
return RENDER_BIT_DEPTH_DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static enum render_bit_depth get_config_render_bit_depth(const struct output_config *oc) {
|
||||||
|
if (oc && oc->render_bit_depth != RENDER_BIT_DEPTH_DEFAULT) {
|
||||||
|
return oc->render_bit_depth;
|
||||||
|
}
|
||||||
|
if (oc && oc->hdr == 1) {
|
||||||
|
return RENDER_BIT_DEPTH_10;
|
||||||
|
}
|
||||||
|
return RENDER_BIT_DEPTH_8;
|
||||||
|
}
|
||||||
|
|
||||||
static bool render_format_is_bgr(uint32_t fmt) {
|
static bool render_format_is_bgr(uint32_t fmt) {
|
||||||
return fmt == DRM_FORMAT_XBGR2101010 || fmt == DRM_FORMAT_XBGR8888;
|
return fmt == DRM_FORMAT_XBGR2101010 || fmt == DRM_FORMAT_XBGR8888;
|
||||||
}
|
}
|
||||||
|
|
@ -485,24 +537,29 @@ static void queue_output_config(struct output_config *oc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oc && oc->render_bit_depth != RENDER_BIT_DEPTH_DEFAULT) {
|
enum render_bit_depth render_bit_depth = get_config_render_bit_depth(oc);
|
||||||
if (oc->render_bit_depth == RENDER_BIT_DEPTH_10 &&
|
if (render_bit_depth == RENDER_BIT_DEPTH_10 &&
|
||||||
bit_depth_from_format(output->wlr_output->render_format) == oc->render_bit_depth) {
|
bit_depth_from_format(output->wlr_output->render_format) == render_bit_depth) {
|
||||||
// 10-bit was set successfully before, try to save some tests by reusing the format
|
// 10-bit was set successfully before, try to save some tests by reusing the format
|
||||||
wlr_output_state_set_render_format(pending, output->wlr_output->render_format);
|
wlr_output_state_set_render_format(pending, output->wlr_output->render_format);
|
||||||
} else if (oc->render_bit_depth == RENDER_BIT_DEPTH_10) {
|
} else if (render_bit_depth == RENDER_BIT_DEPTH_10) {
|
||||||
wlr_output_state_set_render_format(pending, DRM_FORMAT_XRGB2101010);
|
wlr_output_state_set_render_format(pending, DRM_FORMAT_XRGB2101010);
|
||||||
} else if (oc->render_bit_depth == RENDER_BIT_DEPTH_6){
|
} else if (render_bit_depth == RENDER_BIT_DEPTH_6) {
|
||||||
wlr_output_state_set_render_format(pending, DRM_FORMAT_RGB565);
|
wlr_output_state_set_render_format(pending, DRM_FORMAT_RGB565);
|
||||||
} else {
|
|
||||||
wlr_output_state_set_render_format(pending, DRM_FORMAT_XRGB8888);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
wlr_output_state_set_render_format(pending, DRM_FORMAT_XRGB8888);
|
wlr_output_state_set_render_format(pending, DRM_FORMAT_XRGB8888);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool hdr = oc && oc->hdr == 1;
|
||||||
|
if (hdr && oc->color_transform != NULL) {
|
||||||
|
sway_log(SWAY_ERROR, "Cannot HDR on output %s: output has an ICC profile set", wlr_output->name);
|
||||||
|
hdr = false;
|
||||||
|
}
|
||||||
|
set_hdr(wlr_output, pending, hdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool finalize_output_config(struct output_config *oc, struct sway_output *output) {
|
static bool finalize_output_config(struct output_config *oc, struct sway_output *output,
|
||||||
|
const struct wlr_output_state *applied) {
|
||||||
if (output == root->fallback_output) {
|
if (output == root->fallback_output) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -561,6 +618,7 @@ static bool finalize_output_config(struct output_config *oc, struct sway_output
|
||||||
|
|
||||||
output->max_render_time = oc && oc->max_render_time > 0 ? oc->max_render_time : 0;
|
output->max_render_time = oc && oc->max_render_time > 0 ? oc->max_render_time : 0;
|
||||||
output->allow_tearing = oc && oc->allow_tearing > 0;
|
output->allow_tearing = oc && oc->allow_tearing > 0;
|
||||||
|
output->hdr = applied->image_description != NULL;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -785,10 +843,7 @@ static bool search_render_format(struct search_context *ctx, size_t output_idx)
|
||||||
|
|
||||||
const struct wlr_drm_format_set *primary_formats =
|
const struct wlr_drm_format_set *primary_formats =
|
||||||
wlr_output_get_primary_formats(wlr_output, server.allocator->buffer_caps);
|
wlr_output_get_primary_formats(wlr_output, server.allocator->buffer_caps);
|
||||||
enum render_bit_depth needed_bits = RENDER_BIT_DEPTH_8;
|
enum render_bit_depth needed_bits = get_config_render_bit_depth(cfg->config);
|
||||||
if (cfg->config && cfg->config->render_bit_depth != RENDER_BIT_DEPTH_DEFAULT) {
|
|
||||||
needed_bits = cfg->config->render_bit_depth;
|
|
||||||
}
|
|
||||||
for (size_t idx = 0; fmts[idx] != DRM_FORMAT_INVALID; idx++) {
|
for (size_t idx = 0; fmts[idx] != DRM_FORMAT_INVALID; idx++) {
|
||||||
enum render_bit_depth format_bits = bit_depth_from_format(fmts[idx]);
|
enum render_bit_depth format_bits = bit_depth_from_format(fmts[idx]);
|
||||||
if (needed_bits < format_bits) {
|
if (needed_bits < format_bits) {
|
||||||
|
|
@ -943,9 +998,10 @@ static bool apply_resolved_output_configs(struct matched_output_config *configs,
|
||||||
|
|
||||||
for (size_t idx = 0; idx < configs_len; idx++) {
|
for (size_t idx = 0; idx < configs_len; idx++) {
|
||||||
struct matched_output_config *cfg = &configs[idx];
|
struct matched_output_config *cfg = &configs[idx];
|
||||||
|
struct wlr_backend_output_state *backend_state = &states[idx];
|
||||||
sway_log(SWAY_DEBUG, "Finalizing config for %s",
|
sway_log(SWAY_DEBUG, "Finalizing config for %s",
|
||||||
cfg->output->wlr_output->name);
|
cfg->output->wlr_output->name);
|
||||||
finalize_output_config(cfg->config, cfg->output);
|
finalize_output_config(cfg->config, cfg->output, &backend_state->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output layout being applied in finalize_output_config can shift outputs
|
// Output layout being applied in finalize_output_config can shift outputs
|
||||||
|
|
|
||||||
|
|
@ -406,8 +406,8 @@ static void ipc_json_describe_enabled_output(struct sway_output *output,
|
||||||
}
|
}
|
||||||
|
|
||||||
json_object_object_add(object, "max_render_time", json_object_new_int(output->max_render_time));
|
json_object_object_add(object, "max_render_time", json_object_new_int(output->max_render_time));
|
||||||
|
|
||||||
json_object_object_add(object, "allow_tearing", json_object_new_boolean(output->allow_tearing));
|
json_object_object_add(object, "allow_tearing", json_object_new_boolean(output->allow_tearing));
|
||||||
|
json_object_object_add(object, "hdr", json_object_new_boolean(output->hdr));
|
||||||
}
|
}
|
||||||
|
|
||||||
json_object *ipc_json_describe_disabled_output(struct sway_output *output) {
|
json_object *ipc_json_describe_disabled_output(struct sway_output *output) {
|
||||||
|
|
|
||||||
|
|
@ -195,6 +195,7 @@ sway_sources = files(
|
||||||
'commands/output/disable.c',
|
'commands/output/disable.c',
|
||||||
'commands/output/dpms.c',
|
'commands/output/dpms.c',
|
||||||
'commands/output/enable.c',
|
'commands/output/enable.c',
|
||||||
|
'commands/output/hdr.c',
|
||||||
'commands/output/max_render_time.c',
|
'commands/output/max_render_time.c',
|
||||||
'commands/output/mode.c',
|
'commands/output/mode.c',
|
||||||
'commands/output/position.c',
|
'commands/output/position.c',
|
||||||
|
|
|
||||||
|
|
@ -244,6 +244,9 @@ following properties:
|
||||||
|- rect
|
|- rect
|
||||||
: object
|
: object
|
||||||
: The bounds for the output consisting of _x_, _y_, _width_, and _height_
|
: The bounds for the output consisting of _x_, _y_, _width_, and _height_
|
||||||
|
|- hdr
|
||||||
|
: boolean
|
||||||
|
: Whether HDR is enabled
|
||||||
|
|
||||||
|
|
||||||
*Example Reply:*
|
*Example Reply:*
|
||||||
|
|
|
||||||
|
|
@ -210,6 +210,17 @@ must be separated by one space. For example:
|
||||||
|
|
||||||
This setting only has effect when a window is fullscreen on the output.
|
This setting only has effect when a window is fullscreen on the output.
|
||||||
|
|
||||||
|
*output* <name> hdr on|off|toggle
|
||||||
|
Enables or disables HDR (High Dynamic Range). HDR enables a larger color
|
||||||
|
gamut and brightness range. HDR uses the BT2020 primaries and the PQ
|
||||||
|
transfer function.
|
||||||
|
|
||||||
|
When HDR is enabled, _render_bit_depth_ is implicitly set to 10 unless
|
||||||
|
explicitly configured. Using a lower render bit depth may result in color
|
||||||
|
banding artifacts.
|
||||||
|
|
||||||
|
HDR needs to be supported by the output and renderer to be enabled.
|
||||||
|
|
||||||
# SEE ALSO
|
# SEE ALSO
|
||||||
|
|
||||||
*sway*(5) *sway-input*(5)
|
*sway*(5) *sway-input*(5)
|
||||||
|
|
|
||||||
|
|
@ -189,7 +189,8 @@ static void pretty_print_output(json_object *o) {
|
||||||
json_object_object_get_ex(o, "current_workspace", &ws);
|
json_object_object_get_ex(o, "current_workspace", &ws);
|
||||||
json_object_object_get_ex(o, "non_desktop", &non_desktop);
|
json_object_object_get_ex(o, "non_desktop", &non_desktop);
|
||||||
json_object *make, *model, *serial, *scale, *scale_filter, *subpixel,
|
json_object *make, *model, *serial, *scale, *scale_filter, *subpixel,
|
||||||
*transform, *max_render_time, *adaptive_sync_status, *allow_tearing;
|
*transform, *max_render_time, *adaptive_sync_status, *allow_tearing,
|
||||||
|
*hdr;
|
||||||
json_object_object_get_ex(o, "make", &make);
|
json_object_object_get_ex(o, "make", &make);
|
||||||
json_object_object_get_ex(o, "model", &model);
|
json_object_object_get_ex(o, "model", &model);
|
||||||
json_object_object_get_ex(o, "serial", &serial);
|
json_object_object_get_ex(o, "serial", &serial);
|
||||||
|
|
@ -200,6 +201,7 @@ static void pretty_print_output(json_object *o) {
|
||||||
json_object_object_get_ex(o, "max_render_time", &max_render_time);
|
json_object_object_get_ex(o, "max_render_time", &max_render_time);
|
||||||
json_object_object_get_ex(o, "adaptive_sync_status", &adaptive_sync_status);
|
json_object_object_get_ex(o, "adaptive_sync_status", &adaptive_sync_status);
|
||||||
json_object_object_get_ex(o, "allow_tearing", &allow_tearing);
|
json_object_object_get_ex(o, "allow_tearing", &allow_tearing);
|
||||||
|
json_object_object_get_ex(o, "hdr", &hdr);
|
||||||
json_object *x, *y;
|
json_object *x, *y;
|
||||||
json_object_object_get_ex(rect, "x", &x);
|
json_object_object_get_ex(rect, "x", &x);
|
||||||
json_object_object_get_ex(rect, "y", &y);
|
json_object_object_get_ex(rect, "y", &y);
|
||||||
|
|
@ -261,6 +263,7 @@ static void pretty_print_output(json_object *o) {
|
||||||
|
|
||||||
printf(" Allow tearing: %s\n",
|
printf(" Allow tearing: %s\n",
|
||||||
json_object_get_boolean(allow_tearing) ? "yes" : "no");
|
json_object_get_boolean(allow_tearing) ? "yes" : "no");
|
||||||
|
printf(" HDR: %s\n", json_object_get_boolean(hdr) ? "on" : "off");
|
||||||
} else {
|
} else {
|
||||||
printf(
|
printf(
|
||||||
"Output %s '%s %s %s' (disabled)\n",
|
"Output %s '%s %s %s' (disabled)\n",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue