mirror of https://github.com/yshui/picom.git
options: add dithered-present option
See also 0a2cd0f14e
Related: #602
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
parent
0a2cd0f14e
commit
1271839baf
|
@ -268,6 +268,9 @@ May also be one of the predefined kernels: `3x3box` (default), `5x5box`, `7x7box
|
|||
*--window-shader-fg-rule* 'SHADER':'CONDITION'::
|
||||
Specify GLSL fragment shader path for rendering window contents using patterns. Similar to *--opacity-rule*, arguments should be in the format of 'SHADER:CONDITION', e.g. "shader.frag:name = \'window\'". Leading and trailing whitespaces in 'SHADER' will be trimmed. If 'SHADER' is "default", then the default shader will be used for the matching windows. (This also unfortunately means you can't use a shader file named "default"). Does not work when *--legacy-backends* is enabled.
|
||||
|
||||
*--dithered-present*
|
||||
Use higher precision during rendering, and apply dither when presenting the rendered screen. Reduces banding artifacts, but might cause performance degradation. Only works with OpenGL.
|
||||
|
||||
FORMAT OF CONDITIONS
|
||||
--------------------
|
||||
Some options accept a condition string to match certain windows. A condition string is formed by one or more conditions, joined by logical operators.
|
||||
|
|
|
@ -215,6 +215,11 @@ blur-background-exclude = [
|
|||
# backend = "glx"
|
||||
backend = "xrender";
|
||||
|
||||
# Use higher precision during rendering, and apply dither when presenting the
|
||||
# rendered screen. Reduces banding artifacts, but might cause performance
|
||||
# degradation. Only works with OpenGL.
|
||||
dithered-present = false;
|
||||
|
||||
# Enable/disable VSync.
|
||||
# vsync = false
|
||||
vsync = true;
|
||||
|
|
|
@ -259,10 +259,10 @@ bool gl_dual_kawase_blur(double opacity, struct gl_blur_context *bctx, const rec
|
|||
return true;
|
||||
}
|
||||
|
||||
bool gl_blur_impl(double opacity, struct gl_blur_context *bctx, void *mask,
|
||||
coord_t mask_dst, const region_t *reg_blur,
|
||||
const region_t *reg_visible attr_unused, GLuint source_texture,
|
||||
geometry_t source_size, GLuint target_fbo, GLuint default_mask) {
|
||||
bool gl_blur_impl(double opacity, struct gl_blur_context *bctx, void *mask, coord_t mask_dst,
|
||||
const region_t *reg_blur, const region_t *reg_visible attr_unused,
|
||||
GLuint source_texture, geometry_t source_size, GLuint target_fbo,
|
||||
GLuint default_mask, bool high_precision) {
|
||||
bool ret = false;
|
||||
|
||||
if (source_size.width != bctx->fb_width || source_size.height != bctx->fb_height) {
|
||||
|
@ -284,7 +284,11 @@ bool gl_blur_impl(double opacity, struct gl_blur_context *bctx, void *mask,
|
|||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, bctx->blur_textures[i]);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, tex_size->width,
|
||||
GLint format = GL_RGBA8;
|
||||
if (high_precision) {
|
||||
format = GL_RGBA16;
|
||||
}
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format, tex_size->width,
|
||||
tex_size->height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
if (bctx->method == BLUR_METHOD_DUAL_KAWASE) {
|
||||
|
@ -406,7 +410,7 @@ bool gl_blur(backend_t *base, double opacity, void *ctx, void *mask, coord_t mas
|
|||
return gl_blur_impl(opacity, bctx, mask, mask_dst, reg_blur, reg_visible,
|
||||
gd->back_texture,
|
||||
(geometry_t){.width = gd->width, .height = gd->height},
|
||||
gd->back_fbo, gd->default_mask_texture);
|
||||
gd->back_fbo, gd->default_mask_texture, gd->dithered_present);
|
||||
}
|
||||
|
||||
static inline void gl_free_blur_shader(gl_blur_shader_t *shader) {
|
||||
|
|
|
@ -622,13 +622,16 @@ void gl_resize(struct gl_data *gd, int width, int height) {
|
|||
|
||||
gd->height = height;
|
||||
gd->width = width;
|
||||
GLint format = GL_RGB8;
|
||||
if (gd->dithered_present) {
|
||||
format = GL_RGB16;
|
||||
}
|
||||
|
||||
assert(viewport_dimensions[0] >= gd->width);
|
||||
assert(viewport_dimensions[1] >= gd->height);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, gd->back_texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16, width, height, 0, GL_BGR,
|
||||
GL_UNSIGNED_BYTE, NULL);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
gl_check_err();
|
||||
}
|
||||
|
@ -873,9 +876,16 @@ bool gl_init(struct gl_data *gd, session_t *ps) {
|
|||
glUniformMatrix4fv(pml, 1, false, projection_matrix[0]);
|
||||
glUseProgram(0);
|
||||
|
||||
gd->present_prog =
|
||||
gl_create_program_from_strv((const char *[]){present_vertex_shader, NULL},
|
||||
(const char *[]){present_frag, dither_glsl, NULL});
|
||||
gd->dithered_present = ps->o.dithered_present;
|
||||
if (gd->dithered_present) {
|
||||
gd->present_prog = gl_create_program_from_strv(
|
||||
(const char *[]){present_vertex_shader, NULL},
|
||||
(const char *[]){present_frag, dither_glsl, NULL});
|
||||
} else {
|
||||
gd->present_prog = gl_create_program_from_strv(
|
||||
(const char *[]){present_vertex_shader, NULL},
|
||||
(const char *[]){dummy_frag, NULL});
|
||||
}
|
||||
if (!gd->present_prog) {
|
||||
log_error("Failed to create the present shader");
|
||||
return false;
|
||||
|
@ -1281,7 +1291,7 @@ void *gl_shadow_from_mask(backend_t *base, void *mask,
|
|||
1.0, gsctx->blur_context, NULL, (coord_t){0}, ®_blur, NULL,
|
||||
source_texture,
|
||||
(geometry_t){.width = new_inner->width, .height = new_inner->height},
|
||||
fbo, gd->default_mask_texture);
|
||||
fbo, gd->default_mask_texture, gd->dithered_present);
|
||||
pixman_region32_fini(®_blur);
|
||||
}
|
||||
|
||||
|
|
|
@ -109,6 +109,8 @@ struct gl_data {
|
|||
GLuint back_texture, back_fbo;
|
||||
GLuint present_prog;
|
||||
|
||||
bool dithered_present;
|
||||
|
||||
GLuint default_mask_texture;
|
||||
|
||||
/// Called when an gl_texture is decoupled from the texture it refers. Returns
|
||||
|
@ -163,10 +165,10 @@ void *gl_clone(backend_t *base, const void *image_data, const region_t *reg_visi
|
|||
|
||||
bool gl_blur(backend_t *base, double opacity, void *ctx, void *mask, coord_t mask_dst,
|
||||
const region_t *reg_blur, const region_t *reg_visible);
|
||||
bool gl_blur_impl(double opacity, struct gl_blur_context *bctx, void *mask,
|
||||
coord_t mask_dst, const region_t *reg_blur,
|
||||
const region_t *reg_visible attr_unused, GLuint source_texture,
|
||||
geometry_t source_size, GLuint target_fbo, GLuint default_mask);
|
||||
bool gl_blur_impl(double opacity, struct gl_blur_context *bctx, void *mask, coord_t mask_dst,
|
||||
const region_t *reg_blur, const region_t *reg_visible attr_unused,
|
||||
GLuint source_texture, geometry_t source_size, GLuint target_fbo,
|
||||
GLuint default_mask, bool high_precision);
|
||||
void *gl_create_blur_context(backend_t *base, enum blur_method, void *args);
|
||||
void gl_destroy_blur_context(backend_t *base, void *ctx);
|
||||
struct backend_shadow_context *gl_create_shadow_context(backend_t *base, double radius);
|
||||
|
|
|
@ -858,6 +858,10 @@ static void get_blur_size(void *blur_context, int *width, int *height) {
|
|||
}
|
||||
|
||||
static backend_t *backend_xrender_init(session_t *ps) {
|
||||
if (ps->o.dithered_present) {
|
||||
log_warn("\"dithered-present\" is not supported by the xrender backend.");
|
||||
}
|
||||
|
||||
auto xd = ccalloc(1, struct _xrender_data);
|
||||
init_backend_base(&xd->base, ps);
|
||||
|
||||
|
|
|
@ -256,6 +256,8 @@ typedef struct options {
|
|||
/// A list of conditions of windows to which transparent clipping
|
||||
/// should not apply
|
||||
c2_lptr_t *transparent_clipping_blacklist;
|
||||
|
||||
bool dithered_present;
|
||||
} options_t;
|
||||
|
||||
extern const char *const BACKEND_STRS[NUM_BKEND + 1];
|
||||
|
|
|
@ -452,6 +452,8 @@ char *parse_config_libconfig(options_t *opt, const char *config_file, bool *shad
|
|||
lcfg_lookup_bool(&cfg, "no-ewmh-fullscreen", &opt->no_ewmh_fullscreen);
|
||||
// --transparent-clipping
|
||||
lcfg_lookup_bool(&cfg, "transparent-clipping", &opt->transparent_clipping);
|
||||
// --dithered_present
|
||||
lcfg_lookup_bool(&cfg, "dithered-present", &opt->dithered_present);
|
||||
// --transparent-clipping-exclude
|
||||
parse_cfg_condlst(&cfg, &opt->transparent_clipping_blacklist,
|
||||
"transparent-clipping-exclude");
|
||||
|
|
|
@ -168,6 +168,10 @@ static const struct picom_option picom_options[] = {
|
|||
"similar to --opacity-rule. SHADER_PATH can be \"default\", in which case "
|
||||
"the default shader will be used. Does not work when --legacy-backends is "
|
||||
"enabled. See man page for more details"},
|
||||
// 338 is transparent-clipping-exclude
|
||||
{"dithered-present" , no_argument , 339, NULL , "Use higher precision during rendering, and apply dither when presenting the "
|
||||
"rendered screen. Reduces banding artifacts, but might cause performance "
|
||||
"degradation. Only works with OpenGL."},
|
||||
{"legacy-backends" , no_argument , 733, NULL , "Use deprecated version of the backends."},
|
||||
{"monitor-repaint" , no_argument , 800, NULL , "Highlight the updated area of the screen. For debugging."},
|
||||
{"diagnostics" , no_argument , 801, NULL , "Print diagnostic information"},
|
||||
|
@ -716,6 +720,10 @@ bool get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable,
|
|||
// --clip-shadow-above
|
||||
condlst_add(&opt->shadow_clip_list, optarg);
|
||||
break;
|
||||
case 339:
|
||||
// --dithered-present
|
||||
opt->dithered_present = true;
|
||||
break;
|
||||
P_CASEBOOL(733, legacy_backends);
|
||||
P_CASEBOOL(800, monitor_repaint);
|
||||
case 801:
|
||||
|
|
Loading…
Reference in New Issue