diff --git a/include/config.h b/include/config.h index 13700c8..f856dc1 100644 --- a/include/config.h +++ b/include/config.h @@ -11,6 +11,7 @@ struct config_screencast { char *exec_after; char *chooser_cmd; enum xdpw_chooser_types chooser_type; + bool force_mod_linear; }; struct xdpw_config { diff --git a/src/core/config.c b/src/core/config.c index 9722594..77925ea 100644 --- a/src/core/config.c +++ b/src/core/config.c @@ -16,6 +16,7 @@ void print_config(enum LOGLEVEL loglevel, struct xdpw_config *config) { logprint(loglevel, "config: exec_after: %s", config->screencast_conf.exec_after); logprint(loglevel, "config: chooser_cmd: %s", config->screencast_conf.chooser_cmd); logprint(loglevel, "config: chooser_type: %s", chooser_type_str(config->screencast_conf.chooser_type)); + logprint(loglevel, "config: force_mod_linear: %d", config->screencast_conf.force_mod_linear); } // NOTE: calling finish_config won't prepare the config to be read again from config file @@ -47,6 +48,18 @@ static void parse_double(double *dest, const char* value) { *dest = strtod(value, (char**)NULL); } +static void parse_bool(bool *dest, const char* value) { + if (value == NULL || *value == '\0') { + logprint(TRACE, "config: skipping empty value in config file"); + return; + } + if (strcmp(value, "1") == 0) { + *dest = true; + } else { + *dest = false; + } +} + static int handle_ini_screencast(struct config_screencast *screencast_conf, const char *key, const char *value) { if (strcmp(key, "output_name") == 0) { parse_string(&screencast_conf->output_name, value); @@ -63,6 +76,8 @@ static int handle_ini_screencast(struct config_screencast *screencast_conf, cons parse_string(&chooser_type, value); screencast_conf->chooser_type = get_chooser_type(chooser_type); free(chooser_type); + } else if (strcmp(key, "force_mod_linear") == 0) { + parse_bool(&screencast_conf->force_mod_linear, value); } else { logprint(TRACE, "config: skipping invalid key in config file"); return 0; diff --git a/src/screencast/screencast_common.c b/src/screencast/screencast_common.c index ee65a26..c598922 100644 --- a/src/screencast/screencast_common.c +++ b/src/screencast/screencast_common.c @@ -1,3 +1,4 @@ +#include "xdpw.h" #include "screencast_common.h" #include #include @@ -135,10 +136,14 @@ struct xdpw_buffer *xdpw_buffer_create(struct xdpw_screencast_instance *cast, return NULL; } break; - case DMABUF: - buffer->bo = gbm_bo_create(cast->ctx->gbm, - frame_info->width, frame_info->height, frame_info->format, - GBM_BO_USE_RENDERING); + case DMABUF:; + uint32_t flags = GBM_BO_USE_RENDERING; + if (cast->ctx->state->config->screencast_conf.force_mod_linear) { + flags |= GBM_BO_USE_LINEAR; + } + + buffer->bo = gbm_bo_create(cast->ctx->gbm, frame_info->width, frame_info->height, + frame_info->format, flags); if (buffer->bo == NULL) { logprint(ERROR, "xdpw: failed to create gbm_bo"); free(buffer); diff --git a/xdg-desktop-portal-wlr.5.scd b/xdg-desktop-portal-wlr.5.scd index a9c4c48..6cec968 100644 --- a/xdg-desktop-portal-wlr.5.scd +++ b/xdg-desktop-portal-wlr.5.scd @@ -71,6 +71,15 @@ These options need to be placed under the **[screencast]** section. - simple, dmenu: xdpw will launch the chooser given by **chooser_cmd**. For more details see **OUTPUT CHOOSER**. +**force_mod_linear** = _bool_ + Force buffers with implicit modifiers to be linear (experimental) + + Setting this option to 1 will force xdpw to allocate dma-bufs with implicit modifier as linear. + This option shouldn't be required on single gpu setups, but can increase compatibility + especially on setups with multiple gpus. + + This option is experimental and can be removed or replaced in future versions. + ## OUTPUT CHOOSER The chooser can be any program or script with the following behaviour: