mirror of https://github.com/yshui/picom.git
backend: create dual_kawase blur parameters from selected strength [WIP]
**Work-in-Progress** Generate suitable parameters for dual-filter kawase blur based on the selected `blur-strength` or approximate a gauss blur with the selected `blur-size` and std-deviation.
This commit is contained in:
parent
33c5a5a36b
commit
d45d0ca209
|
@ -363,6 +363,69 @@ struct conv **generate_blur_kernel(enum blur_method method, void *args, int *ker
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/// Generate kernel parameters for dual-kawase blur method. Falls back on approximating
|
||||
/// standard gauss radius if strength is zero or below.
|
||||
struct dual_kawase_params *generate_dual_kawase_params(void *args) {
|
||||
struct dual_kawase_blur_args *blur_args = args;
|
||||
static const struct {
|
||||
int iterations; /// Number of down- and upsample iterations
|
||||
float offset; /// Sample offset in half-pixels
|
||||
int min_radius; /// Approximate gauss-blur with at least this
|
||||
/// radius and std-deviation
|
||||
} strength_levels[20] = {
|
||||
{.iterations = 1, .offset = 1.25f, .min_radius = 1}, // LVL 1
|
||||
{.iterations = 1, .offset = 2.25f, .min_radius = 6}, // LVL 2
|
||||
{.iterations = 2, .offset = 2.00f, .min_radius = 11}, // LVL 3
|
||||
{.iterations = 2, .offset = 3.00f, .min_radius = 17}, // LVL 4
|
||||
{.iterations = 2, .offset = 4.25f, .min_radius = 24}, // LVL 5
|
||||
{.iterations = 3, .offset = 2.50f, .min_radius = 32}, // LVL 6
|
||||
{.iterations = 3, .offset = 3.25f, .min_radius = 40}, // LVL 7
|
||||
{.iterations = 3, .offset = 4.25f, .min_radius = 51}, // LVL 8
|
||||
{.iterations = 3, .offset = 5.50f, .min_radius = 67}, // LVL 9
|
||||
{.iterations = 4, .offset = 3.25f, .min_radius = 83}, // LVL 10
|
||||
{.iterations = 4, .offset = 4.00f, .min_radius = 101}, // LVL 11
|
||||
{.iterations = 4, .offset = 5.00f, .min_radius = 123}, // LVL 12
|
||||
{.iterations = 4, .offset = 6.00f, .min_radius = 148}, // LVL 13
|
||||
{.iterations = 4, .offset = 7.25f, .min_radius = 178}, // LVL 14
|
||||
{.iterations = 4, .offset = 8.25f, .min_radius = 208}, // LVL 15
|
||||
{.iterations = 5, .offset = 4.50f, .min_radius = 236}, // LVL 16
|
||||
{.iterations = 5, .offset = 5.25f, .min_radius = 269}, // LVL 17
|
||||
{.iterations = 5, .offset = 6.25f, .min_radius = 309}, // LVL 18
|
||||
{.iterations = 5, .offset = 7.25f, .min_radius = 357}, // LVL 19
|
||||
{.iterations = 5, .offset = 8.50f, .min_radius = 417}, // LVL 20
|
||||
};
|
||||
|
||||
auto params = ccalloc(1, struct dual_kawase_params);
|
||||
params->iterations = 0;
|
||||
params->offset = 1.0f;
|
||||
|
||||
if (blur_args->strength <= 0 && blur_args->size) {
|
||||
// find highest level that approximates blur-strength with the selected
|
||||
// gaussian blur-radius
|
||||
int lvl = 1;
|
||||
while (strength_levels[lvl - 1].min_radius < blur_args->size && lvl < 20) {
|
||||
++lvl;
|
||||
}
|
||||
blur_args->strength = lvl;
|
||||
}
|
||||
if (blur_args->strength <= 0) {
|
||||
// default value
|
||||
blur_args->strength = 5;
|
||||
}
|
||||
|
||||
assert(blur_args->strength > 0 && blur_args->strength <= 20);
|
||||
params->iterations = strength_levels[blur_args->strength - 1].iterations;
|
||||
params->offset = strength_levels[blur_args->strength - 1].offset;
|
||||
|
||||
// Expand sample area to cover the smallest texture / highest selected iteration:
|
||||
// - Smallest texture dimensions are halved `iterations`-times
|
||||
// - Upsample needs pixels two-times `offset` away from the border
|
||||
// - Plus one for interpolation differences
|
||||
params->expand = (1 << params->iterations) * 2 * (int)ceil(params->offset) + 1;
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
void init_backend_base(struct backend_base *base, session_t *ps) {
|
||||
base->c = ps->c;
|
||||
base->loop = ps->loop;
|
||||
|
|
|
@ -16,6 +16,15 @@ typedef struct conv conv;
|
|||
typedef struct backend_base backend_t;
|
||||
struct backend_operations;
|
||||
|
||||
struct dual_kawase_params {
|
||||
/// Number of downsample passes
|
||||
int iterations;
|
||||
/// Pixel offset for down- and upsample
|
||||
float offset;
|
||||
/// Save area around blur target (@ref resize_width, @ref resize_height)
|
||||
int expand;
|
||||
};
|
||||
|
||||
bool build_shadow(xcb_connection_t *, xcb_drawable_t, double opacity, int width,
|
||||
int height, const conv *kernel, xcb_render_picture_t shadow_pixel,
|
||||
xcb_pixmap_t *pixmap, xcb_render_picture_t *pict);
|
||||
|
@ -41,3 +50,4 @@ default_backend_render_shadow(backend_t *backend_data, int width, int height,
|
|||
void init_backend_base(struct backend_base *base, session_t *ps);
|
||||
|
||||
struct conv **generate_blur_kernel(enum blur_method method, void *args, int *kernel_count);
|
||||
struct dual_kawase_params *generate_dual_kawase_params(void *args);
|
||||
|
|
Loading…
Reference in New Issue