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 11 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
28 changes: 20 additions & 8 deletions include/render/fx_renderer/fx_renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ 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);

Expand Down Expand Up @@ -141,20 +145,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
35 changes: 33 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,16 @@ 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_options {
ErikReider marked this conversation as resolved.
Show resolved Hide resolved
struct fx_render_texture_options tex_options;
struct wlr_scene_buffer *scene_buffer;
struct wlr_output *output;
struct wlr_box monitor_box;
struct fx_framebuffer *current_buffer;
struct blur_data *blur_data;
bool ignore_transparent;
};

/**
* Render a fx texture.
*/
Expand All @@ -66,4 +78,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_options *fx_options);

/**
* Render optimized blur.
*/
void fx_render_pass_add_optimized_blur(struct fx_gles_render_pass *pass,
struct fx_render_blur_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
1 change: 1 addition & 0 deletions include/scenefx/fx_renderer/fx_renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define SCENEFX_FX_OPENGL_H

#include <wlr/backend.h>
#include <wlr/render/allocator.h>
ErikReider marked this conversation as resolved.
Show resolved Hide resolved

struct wlr_renderer *fx_renderer_create_with_drm_fd(int drm_fd);
struct wlr_renderer *fx_renderer_create(struct wlr_backend *backend);
Expand Down
26 changes: 26 additions & 0 deletions include/scenefx/types/fx/blur_data.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#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 scene_buffer_should_blur(bool backdrop_blur, struct blur_data *blur_data);

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
4 changes: 2 additions & 2 deletions include/scenefx/types/fx/shadow_data.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef TYPES_DECORATION_DATA
#define TYPES_DECORATION_DATA
#ifndef TYPES_FX_SHADOW_DATA_H
#define TYPES_FX_SHADOW_DATA_H

#include <stdbool.h>
#include <wlr/util/addon.h>
Expand Down
40 changes: 39 additions & 1 deletion include/scenefx/types/wlr_scene.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include <pixman.h>
#include "scenefx/types/fx/shadow_data.h"
#include "scenefx/types/fx/blur_data.h"
#include <time.h>
#include <wayland-server-core.h>
#include <wlr/render/wlr_renderer.h>
Expand Down Expand Up @@ -111,6 +112,8 @@ struct wlr_scene {
enum wlr_scene_debug_damage_option debug_damage_option;
bool direct_scanout;
bool calculate_visibility;

struct blur_data blur_data;
};

/** A scene-graph node displaying a single surface. */
Expand Down Expand Up @@ -176,9 +179,13 @@ struct wlr_scene_buffer {
*/
struct wlr_scene_output *primary_output;

float opacity;
int corner_radius;
struct shadow_data shadow_data;
bool backdrop_blur;
bool backdrop_blur_optimized;
bool backdrop_blur_ignore_transparent;

float opacity;
enum wlr_scale_filter_mode filter_mode;
struct wlr_fbox src_box;
int dst_width, dst_height;
Expand Down Expand Up @@ -313,6 +320,9 @@ struct wlr_scene *wlr_scene_create(void);
void wlr_scene_set_presentation(struct wlr_scene *scene,
struct wlr_presentation *presentation);

/** Sets the global blur parameters */
void wlr_scene_set_blur_data(struct wlr_scene *scene, struct blur_data blur_data);

/**
* Handles linux_dmabuf_v1 feedback for all surfaces in the scene.
*
Expand Down Expand Up @@ -461,6 +471,34 @@ void wlr_scene_buffer_set_corner_radius(struct wlr_scene_buffer *scene_buffer,
void wlr_scene_buffer_set_shadow_data(struct wlr_scene_buffer *scene_buffer,
struct shadow_data shadow_data);

/**
* Sets the whether or not the buffer should render backdrop blur
*/
void wlr_scene_buffer_set_backdrop_blur(struct wlr_scene_buffer *scene_buffer,
bool enabled);

/**
* Sets the whether the backdrop blur should use optimized blur or not
*/
void wlr_scene_buffer_set_backdrop_blur_optimized(struct wlr_scene_buffer *scene_buffer,
bool enabled);

/**
* Sets the whether the backdrop blur should not render in fully transparent
* segments.
*/
void wlr_scene_buffer_set_backdrop_blur_ignore_transparent(
struct wlr_scene_buffer *scene_buffer, bool enabled);

/**
* Tells the renderer to re-render the optimized blur. Very expensive so should
* only be called when needed.
*
* An example use would be to call this when a "static" node changes, like a
* wallpaper.
*/
void wlr_scene_optimized_blur_mark_dirty(struct wlr_scene *scene);

/**
* Calls the buffer's frame_done signal.
*/
Expand Down
33 changes: 33 additions & 0 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 @@ -128,6 +159,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