From 83e1cd9a19ec47e678a0ea6f07f15ba016b56274 Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Thu, 11 Aug 2022 04:53:14 +0100 Subject: [PATCH] backend: add and implement get_shader_attributes Used for passing back information about whether a shader needs to be re-rendered every frame. Signed-off-by: Yuxuan Shui --- src/backend/backend.h | 16 ++++++++++++++++ src/backend/gl/gl_common.c | 9 +++++++++ src/backend/gl/gl_common.h | 1 + src/backend/gl/glx.c | 1 + src/common.h | 1 + src/picom.c | 8 ++++++++ 6 files changed, 36 insertions(+) diff --git a/src/backend/backend.h b/src/backend/backend.h index ff60ae1..31732fb 100644 --- a/src/backend/backend.h +++ b/src/backend/backend.h @@ -80,6 +80,12 @@ enum image_operations { IMAGE_OP_APPLY_ALPHA, }; +enum shader_attributes { + // Whether the shader needs to be render regardless of whether the window is + // updated. + SHADER_ATTRIBUTE_ANIMATED = 1, +}; + struct gaussian_blur_args { int size; double deviation; @@ -203,13 +209,23 @@ struct backend_operations { void (*release_image)(backend_t *backend_data, void *img_data) attr_nonnull(1, 2); /// Create a shader object from a shader source. + /// + /// Optional void *(*create_shader)(backend_t *backend_data, const char *source)attr_nonnull(1, 2); /// Free a shader object. + /// + /// Required if create_shader is present. void (*destroy_shader)(backend_t *backend_data, void *shader) attr_nonnull(1, 2); // =========== Query =========== + /// Get the attributes of a shader. + /// + /// Optional, Returns a bitmask of attributes, see `shader_attributes`. + uint64_t (*get_shader_attributes)(backend_t *backend_data, void *shader) + attr_nonnull(1, 2); + /// Return if image is not completely opaque. /// /// This function is needed because some backend might change the content of the diff --git a/src/backend/gl/gl_common.c b/src/backend/gl/gl_common.c index f49e450..ed757f2 100644 --- a/src/backend/gl/gl_common.c +++ b/src/backend/gl/gl_common.c @@ -1682,6 +1682,15 @@ void *gl_create_window_shader(backend_t *backend_data attr_unused, const char *s return win_shader; } +uint64_t gl_get_shader_attributes(backend_t *backend_data attr_unused, void *shader) { + auto win_shader = (gl_win_shader_t *)shader; + uint64_t ret = 0; + if (glGetUniformLocation(win_shader->prog, "time") >= 0) { + ret |= SHADER_ATTRIBUTE_ANIMATED; + } + return ret; +} + bool gl_init(struct gl_data *gd, session_t *ps) { // Initialize GLX data structure glDisable(GL_DEPTH_TEST); diff --git a/src/backend/gl/gl_common.h b/src/backend/gl/gl_common.h index 0db5bf7..9336d74 100644 --- a/src/backend/gl/gl_common.h +++ b/src/backend/gl/gl_common.h @@ -110,6 +110,7 @@ GLuint gl_create_program(const GLuint *const shaders, int nshaders); GLuint gl_create_program_from_str(const char *vert_shader_str, const char *frag_shader_str); void *gl_create_window_shader(backend_t *backend_data, const char *source); void gl_destroy_window_shader(backend_t *backend_data, void *shader); +uint64_t gl_get_shader_attributes(backend_t *backend_data, void *shader); bool gl_set_image_property(backend_t *backend_data, enum image_properties prop, void *image_data, void *args); diff --git a/src/backend/gl/glx.c b/src/backend/gl/glx.c index 11a3c85..f8cb7ef 100644 --- a/src/backend/gl/glx.c +++ b/src/backend/gl/glx.c @@ -549,6 +549,7 @@ struct backend_operations glx_ops = { .device_status = gl_device_status, .create_shader = gl_create_window_shader, .destroy_shader = gl_destroy_window_shader, + .get_shader_attributes = gl_get_shader_attributes, .max_buffer_age = 5, // Why? }; diff --git a/src/common.h b/src/common.h index 6154e5f..a68565b 100644 --- a/src/common.h +++ b/src/common.h @@ -134,6 +134,7 @@ struct shader_info { char *key; char *source; void *backend_shader; + uint64_t attributes; UT_hash_handle hh; }; diff --git a/src/picom.c b/src/picom.c index 116a2ed..7490df0 100644 --- a/src/picom.c +++ b/src/picom.c @@ -519,6 +519,14 @@ static bool initialize_backend(session_t *ps) { log_warn("Failed to create shader for shader file %s, " "this shader will not be used", shader->key); + } else { + if (ps->backend_data->ops->get_shader_attributes) { + shader->attributes = + ps->backend_data->ops->get_shader_attributes( + ps->backend_data, shader->backend_shader); + } else { + shader->attributes = 0; + } } }