diff options
author | Erik Reider <[email protected]> | 2024-02-27 18:05:58 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2024-02-27 18:05:58 +0100 |
commit | 7f0883b383b73af7bc68dcf8c2ee845c5eab5807 (patch) | |
tree | ff13a416200ac372d0ae303e5996bb9a22f819dd /render/fx_renderer/fx_renderer.c | |
parent | 5b6862c981eb5541888f625cd93e7775cabe06b0 (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.c | 84 |
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) { |