summaryrefslogtreecommitdiff
path: root/render/fx_renderer/fx_renderer.c
diff options
context:
space:
mode:
authorErik Reider <[email protected]>2024-02-27 18:05:58 +0100
committerGitHub <[email protected]>2024-02-27 18:05:58 +0100
commit7f0883b383b73af7bc68dcf8c2ee845c5eab5807 (patch)
treeff13a416200ac372d0ae303e5996bb9a22f819dd /render/fx_renderer/fx_renderer.c
parent5b6862c981eb5541888f625cd93e7775cabe06b0 (diff)
[FX Renderer] Add blur (#30)
* Initial blur implementation * Added additional blur effects from SwayFX * Simplified blur pass functions to match the other pass functions * Minor fixes * Added support for optimized blur * tinywl: Don't set decoration values every frame * Updated public blur function docs * Simplified blur buffer management * Moved ignore transparent bool into a per buffer option * Clip the scene_buffer when blur is enabled * Added back corner and shadow checks in opaque_region function * Renamed fx_render_blur_options to fx_render_blur_pass_options * Fixed nits * Removed unused fx_framebuffer_bind_wlr_fbo function * Removed wlr_scene impl. Should be moved into future PR instead * Made blur impl independent of wlr_scene * Moved shader init back into fx_renderer.c * Renamed fx_framebuffer_get_or_create_bufferless to fx_framebuffer_get_or_create_custom
Diffstat (limited to 'render/fx_renderer/fx_renderer.c')
-rw-r--r--render/fx_renderer/fx_renderer.c84
1 files changed, 72 insertions, 12 deletions
diff --git a/render/fx_renderer/fx_renderer.c b/render/fx_renderer/fx_renderer.c
index 0b20d7e..0923555 100644
--- a/render/fx_renderer/fx_renderer.c
+++ b/render/fx_renderer/fx_renderer.c
@@ -66,7 +66,7 @@ struct fx_render_timer *fx_get_render_timer(struct wlr_render_timer *wlr_timer)
return timer;
}
-static bool fx_bind_main_buffer(struct wlr_renderer *wlr_renderer,
+static bool fx_bind_buffer(struct wlr_renderer *wlr_renderer,
struct wlr_buffer *wlr_buffer) {
struct fx_renderer *renderer = fx_get_renderer(wlr_renderer);
@@ -138,6 +138,8 @@ static bool fx_renderer_begin(struct wlr_renderer *wlr_renderer, uint32_t width,
renderer->viewport_width = width;
renderer->viewport_height = height;
+ pixman_region32_init(&renderer->blur_padding_region);
+
// refresh projection matrix
matrix_projection(renderer->projection, width, height,
WL_OUTPUT_TRANSFORM_FLIPPED_180);
@@ -153,8 +155,8 @@ static bool fx_renderer_begin(struct wlr_renderer *wlr_renderer, uint32_t width,
}
static void fx_renderer_end(struct wlr_renderer *wlr_renderer) {
- fx_get_renderer_in_context(wlr_renderer);
- // no-op
+ struct fx_renderer *renderer = fx_get_renderer_in_context(wlr_renderer);
+ pixman_region32_fini(&renderer->blur_padding_region);
}
static void fx_renderer_clear(struct wlr_renderer *wlr_renderer,
@@ -239,6 +241,7 @@ static bool fx_render_subtexture_with_matrix(
glUniform2f(shader->size, box->width, box->height);
glUniform2f(shader->position, box->x, box->y);
glUniform1f(shader->radius, 0);
+ glUniform1f(shader->discard_transparent, false);
float tex_matrix[9];
wlr_matrix_identity(tex_matrix);
@@ -451,7 +454,7 @@ static void fx_renderer_destroy(struct wlr_renderer *wlr_renderer) {
static struct wlr_render_pass *begin_buffer_pass(struct wlr_renderer *wlr_renderer,
struct wlr_buffer *wlr_buffer, const struct wlr_buffer_pass_options *options) {
struct fx_gles_render_pass *pass =
- fx_renderer_begin_buffer_pass(wlr_renderer, wlr_buffer, options);
+ fx_renderer_begin_buffer_pass(wlr_renderer, wlr_buffer, NULL, options);
if (!pass) {
return NULL;
}
@@ -530,7 +533,7 @@ static void fx_render_timer_destroy(struct wlr_render_timer *wlr_timer) {
static const struct wlr_renderer_impl renderer_impl = {
.destroy = fx_renderer_destroy,
- .bind_buffer = fx_bind_main_buffer,
+ .bind_buffer = fx_bind_buffer,
.begin = fx_renderer_begin,
.end = fx_renderer_end,
.clear = fx_renderer_clear,
@@ -629,6 +632,67 @@ struct wlr_renderer *fx_renderer_create(struct wlr_backend *backend) {
return renderer_autocreate(backend, -1);
}
+static bool link_shaders(struct fx_renderer *renderer) {
+ // quad fragment shader
+ if (!link_quad_program(&renderer->shaders.quad)) {
+ wlr_log(WLR_ERROR, "Could not link quad shader");
+ goto error;
+ }
+ // fragment shaders
+ if (!link_tex_program(&renderer->shaders.tex_rgba, SHADER_SOURCE_TEXTURE_RGBA)) {
+ wlr_log(WLR_ERROR, "Could not link tex_RGBA shader");
+ goto error;
+ }
+ if (!link_tex_program(&renderer->shaders.tex_rgbx, SHADER_SOURCE_TEXTURE_RGBX)) {
+ wlr_log(WLR_ERROR, "Could not link tex_RGBX shader");
+ goto error;
+ }
+ if (!link_tex_program(&renderer->shaders.tex_ext, SHADER_SOURCE_TEXTURE_EXTERNAL)) {
+ wlr_log(WLR_ERROR, "Could not link tex_EXTERNAL shader");
+ goto error;
+ }
+
+ // stencil mask shader
+ if (!link_stencil_mask_program(&renderer->shaders.stencil_mask)) {
+ wlr_log(WLR_ERROR, "Could not link stencil mask shader");
+ goto error;
+ }
+ // box shadow shader
+ if (!link_box_shadow_program(&renderer->shaders.box_shadow)) {
+ wlr_log(WLR_ERROR, "Could not link box shadow shader");
+ goto error;
+ }
+
+ // Blur shaders
+ if (!link_blur1_program(&renderer->shaders.blur1)) {
+ wlr_log(WLR_ERROR, "Could not link blur1 shader");
+ goto error;
+ }
+ if (!link_blur2_program(&renderer->shaders.blur2)) {
+ wlr_log(WLR_ERROR, "Could not link blur2 shader");
+ goto error;
+ }
+ if (!link_blur_effects_program(&renderer->shaders.blur_effects)) {
+ wlr_log(WLR_ERROR, "Could not link blur_effects shader");
+ goto error;
+ }
+
+ return true;
+
+error:
+ glDeleteProgram(renderer->shaders.quad.program);
+ glDeleteProgram(renderer->shaders.tex_rgba.program);
+ glDeleteProgram(renderer->shaders.tex_rgbx.program);
+ glDeleteProgram(renderer->shaders.tex_ext.program);
+ glDeleteProgram(renderer->shaders.stencil_mask.program);
+ glDeleteProgram(renderer->shaders.box_shadow.program);
+ glDeleteProgram(renderer->shaders.blur1.program);
+ glDeleteProgram(renderer->shaders.blur2.program);
+ glDeleteProgram(renderer->shaders.blur_effects.program);
+
+ return false;
+}
+
struct wlr_renderer *fx_renderer_create_egl(struct wlr_egl *egl) {
if (!wlr_egl_make_current(egl)) {
return NULL;
@@ -751,6 +815,9 @@ struct wlr_renderer *fx_renderer_create_egl(struct wlr_egl *egl) {
if (!link_shaders(renderer)) {
goto error;
}
+
+ renderer->blur_buffer_dirty = false;
+
pop_fx_debug(renderer);
wlr_log(WLR_INFO, "FX RENDERER: Shaders Initialized Successfully");
@@ -760,13 +827,6 @@ struct wlr_renderer *fx_renderer_create_egl(struct wlr_egl *egl) {
return &renderer->wlr_renderer;
error:
- glDeleteProgram(renderer->shaders.quad.program);
- glDeleteProgram(renderer->shaders.tex_rgba.program);
- glDeleteProgram(renderer->shaders.tex_rgbx.program);
- glDeleteProgram(renderer->shaders.tex_ext.program);
- glDeleteProgram(renderer->shaders.stencil_mask.program);
- glDeleteProgram(renderer->shaders.box_shadow.program);
-
pop_fx_debug(renderer);
if (renderer->exts.KHR_debug) {