Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FX Renderer] Add blur #30

Merged
merged 18 commits into from
Feb 27, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 20 additions & 11 deletions include/render/fx_renderer/fx_renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

#include "render/fx_renderer/shaders.h"
#include "render/pass.h"
#include "scenefx/types/fx/shadow_data.h"

struct fx_pixel_format {
uint32_t drm_format;
Expand Down Expand Up @@ -48,13 +47,15 @@ struct fx_framebuffer {
struct wlr_addon addon;
};

/** Should only be used with custom fbs */
void fx_framebuffer_get_or_create_bufferless(struct fx_renderer *fx_renderer,
struct wlr_output *output, struct fx_framebuffer **fx_buffer);

struct fx_framebuffer *fx_framebuffer_get_or_create(struct fx_renderer *renderer,
struct wlr_buffer *wlr_buffer);

void fx_framebuffer_bind(struct fx_framebuffer *buffer);

void fx_framebuffer_bind_wlr_fbo(struct fx_renderer *renderer);

void fx_framebuffer_destroy(struct fx_framebuffer *buffer);

///
Expand Down Expand Up @@ -141,20 +142,28 @@ struct fx_renderer {
PFNGLGETINTEGER64VEXTPROC glGetInteger64vEXT;
} procs;

struct {
struct quad_shader quad;
struct tex_shader tex_rgba;
struct tex_shader tex_rgbx;
struct tex_shader tex_ext;
struct box_shadow_shader box_shadow;
struct stencil_mask_shader stencil_mask;
} shaders;
struct shaders shaders;
ErikReider marked this conversation as resolved.
Show resolved Hide resolved

struct wl_list buffers; // fx_framebuffer.link
struct wl_list textures; // fx_texture.link

struct fx_framebuffer *current_buffer;
uint32_t viewport_width, viewport_height;

// Contains the blurred background for tiled windows
struct fx_framebuffer *optimized_blur_buffer;
// Contains the original pixels to draw over the areas where artifact are visible
struct fx_framebuffer *blur_saved_pixels_buffer;
// Blur swaps between the two effects buffers everytime it scales the image
// Buffer used for effects
struct fx_framebuffer *effects_buffer;
// Swap buffer used for effects
struct fx_framebuffer *effects_buffer_swapped;

// The region where there's blur
pixman_region32_t blur_padding_region;

bool blur_buffer_dirty;
};

bool wlr_renderer_is_fx(struct wlr_renderer *wlr_renderer);
Expand Down
35 changes: 35 additions & 0 deletions include/render/fx_renderer/shaders.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ struct tex_shader {
GLint size;
GLint position;
GLint radius;
GLint discard_transparent;
};

struct stencil_mask_shader {
Expand All @@ -60,6 +61,40 @@ struct box_shadow_shader {
GLint corner_radius;
};

struct blur_shader {
GLuint program;
GLint proj;
GLint tex_proj;
GLint tex;
GLint pos_attrib;
GLint radius;
GLint halfpixel;
};

struct blur_effects_shader {
GLuint program;
GLint proj;
GLint tex_proj;
GLint tex;
GLint pos_attrib;
GLfloat noise;
GLfloat brightness;
GLfloat contrast;
GLfloat saturation;
};

struct shaders {
struct quad_shader quad;
struct tex_shader tex_rgba;
struct tex_shader tex_rgbx;
struct tex_shader tex_ext;
struct box_shadow_shader box_shadow;
struct stencil_mask_shader stencil_mask;
struct blur_shader blur1;
struct blur_shader blur2;
struct blur_effects_shader blur_effects;
};
ErikReider marked this conversation as resolved.
Show resolved Hide resolved

bool link_shaders(struct fx_renderer *renderer);

#endif
36 changes: 34 additions & 2 deletions include/render/pass.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,16 @@ struct fx_gles_render_pass {
* Callers must call wlr_render_pass_submit() once they are done with the
* render pass.
*/
struct fx_gles_render_pass *fx_renderer_begin_buffer_pass(struct wlr_renderer *renderer,
struct wlr_buffer *buffer, const struct wlr_buffer_pass_options *options);
struct fx_gles_render_pass *fx_renderer_begin_buffer_pass(struct wlr_renderer *wlr_renderer,
struct wlr_buffer *wlr_buffer, struct wlr_output *output,
const struct wlr_buffer_pass_options *options);

struct fx_render_texture_options {
struct wlr_render_texture_options base;
float scale;
struct wlr_box *clip_box; // Used to clip csd. Ignored if NULL
int corner_radius;
bool discard_transparent;
};

struct fx_render_texture_options fx_render_texture_options_default(
Expand All @@ -41,6 +43,17 @@ struct fx_render_rect_options {
struct fx_render_rect_options fx_render_rect_options_default(
const struct wlr_render_rect_options *base);

struct fx_render_blur_pass_options {
struct fx_render_texture_options tex_options;
pixman_region32_t *opaque_region;
struct wlr_output *output;
struct wlr_box monitor_box;
struct fx_framebuffer *current_buffer;
struct blur_data *blur_data;
bool use_optimized_blur;
bool ignore_transparent;
};

/**
* Render a fx texture.
*/
Expand All @@ -66,4 +79,23 @@ void fx_render_pass_add_box_shadow(struct fx_gles_render_pass *pass,
const struct fx_render_rect_options *fx_options,
int corner_radius, struct shadow_data *shadow_data);

/**
* Render blur.
*/
void fx_render_pass_add_blur(struct fx_gles_render_pass *pass,
struct fx_render_blur_pass_options *fx_options);

/**
* Render optimized blur.
*/
void fx_render_pass_add_optimized_blur(struct fx_gles_render_pass *pass,
struct fx_render_blur_pass_options *fx_options);

/**
* Render from one buffer to another
*/
void fx_renderer_read_to_buffer(struct fx_gles_render_pass *pass,
pixman_region32_t *region, struct fx_framebuffer *dst_buffer,
struct fx_framebuffer *src_buffer);

#endif
24 changes: 24 additions & 0 deletions include/scenefx/types/fx/blur_data.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#ifndef TYPES_FX_BLUR_DATA_H
#define TYPES_FX_BLUR_DATA_H

#include <stdbool.h>
#include <wlr/util/addon.h>

struct blur_data {
int num_passes;
int radius;
float noise;
float brightness;
float contrast;
float saturation;
};

struct blur_data blur_data_get_default(void);

bool blur_data_should_parameters_blur_effects(struct blur_data *blur_data);

bool blur_data_cmp(struct blur_data *a, struct blur_data *b);

int blur_data_calc_size(struct blur_data *blur_data);

#endif
1 change: 1 addition & 0 deletions include/scenefx/types/wlr_scene.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ struct wlr_scene_buffer {
float opacity;
int corner_radius;
struct shadow_data shadow_data;

enum wlr_scale_filter_mode filter_mode;
struct wlr_fbox src_box;
int dst_width, dst_height;
Expand Down
37 changes: 33 additions & 4 deletions render/fx_renderer/fx_framebuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,37 @@ static const struct wlr_addon_interface buffer_addon_impl = {
.destroy = handle_buffer_destroy,
};

void fx_framebuffer_get_or_create_bufferless(struct fx_renderer *renderer,
ErikReider marked this conversation as resolved.
Show resolved Hide resolved
struct wlr_output *output, struct fx_framebuffer **fx_framebuffer) {
struct wlr_allocator *allocator = output->allocator;
struct wlr_swapchain *swapchain = output->swapchain;
int width = output->width;
int height = output->height;
struct wlr_buffer *wlr_buffer = NULL;

if (*fx_framebuffer == NULL) {
wlr_buffer = wlr_allocator_create_buffer(allocator, width, height,
&swapchain->format);
if (wlr_buffer == NULL) {
wlr_log(WLR_ERROR, "Failed to allocate buffer");
return;
}
} else {
if ((wlr_buffer = (*fx_framebuffer)->buffer) &&
wlr_buffer->width == width &&
wlr_buffer->height == height) {
return;
}
// Create a new wlr_buffer if it's null or if the output size has
// changed
fx_framebuffer_destroy(*fx_framebuffer);
wlr_buffer_drop(wlr_buffer);
wlr_buffer = wlr_allocator_create_buffer(allocator,
width, height, &swapchain->format);
}
*fx_framebuffer = fx_framebuffer_get_or_create(renderer, wlr_buffer);
}

struct fx_framebuffer *fx_framebuffer_get_or_create(struct fx_renderer *renderer,
struct wlr_buffer *wlr_buffer) {
struct wlr_addon *addon =
Expand Down Expand Up @@ -111,10 +142,6 @@ void fx_framebuffer_bind(struct fx_framebuffer *fx_buffer) {
glBindFramebuffer(GL_FRAMEBUFFER, fx_buffer->fbo);
}

void fx_framebuffer_bind_wlr_fbo(struct fx_renderer *renderer) {
glBindFramebuffer(GL_FRAMEBUFFER, renderer->current_buffer->fbo);
}

void fx_framebuffer_destroy(struct fx_framebuffer *fx_buffer) {
// Release the framebuffer
wl_list_remove(&fx_buffer->link);
Expand All @@ -128,6 +155,8 @@ void fx_framebuffer_destroy(struct fx_framebuffer *fx_buffer) {
fx_buffer->fbo = -1;
glDeleteRenderbuffers(1, &fx_buffer->rbo);
fx_buffer->rbo = -1;
glDeleteRenderbuffers(1, &fx_buffer->sb);
fx_buffer->sb = -1;

wlr_egl_destroy_image(fx_buffer->renderer->egl, fx_buffer->image);

Expand Down
Loading