diff options
Diffstat (limited to 'render')
-rw-r--r-- | render/fx_renderer/fx_pass.c | 50 | ||||
-rw-r--r-- | render/fx_renderer/gles2/shaders/box_shadow.frag | 10 | ||||
-rw-r--r-- | render/fx_renderer/shaders.c | 4 |
3 files changed, 33 insertions, 31 deletions
diff --git a/render/fx_renderer/fx_pass.c b/render/fx_renderer/fx_pass.c index f0af02b..5d28c27 100644 --- a/render/fx_renderer/fx_pass.c +++ b/render/fx_renderer/fx_pass.c @@ -16,7 +16,6 @@ #include "scenefx/render/fx_renderer/fx_renderer.h" #include "scenefx/render/fx_renderer/fx_effect_framebuffers.h" #include "scenefx/types/fx/blur_data.h" -#include "scenefx/types/fx/shadow_data.h" #define MAX_QUADS 86 // 4kb @@ -453,28 +452,26 @@ void fx_render_pass_add_rounded_border_corner(struct fx_gles_render_pass *pass, void fx_render_pass_add_box_shadow(struct fx_gles_render_pass *pass, const struct fx_render_box_shadow_options *options) { struct fx_renderer *renderer = pass->buffer->renderer; - struct shadow_data *shadow_data = options->shadow_data; - const struct wlr_render_color *color = &shadow_data->color; - struct wlr_box shadow_box = options->shadow_box; - assert(shadow_box.width > 0 && shadow_box.height > 0); + struct wlr_box box = options->box; + assert(box.width > 0 && box.height > 0); - struct wlr_box surface_box = options->clip_box; + const struct wlr_box window_box = options->window_box; - pixman_region32_t render_region; - pixman_region32_init(&render_region); - - pixman_region32_t inner_region; - pixman_region32_init_rect(&inner_region, - surface_box.x + options->corner_radius * 0.3, - surface_box.y + options->corner_radius * 0.3, - fmax(surface_box.width - options->corner_radius * 0.6, 0), - fmax(surface_box.height - options->corner_radius * 0.6, 0)); - pixman_region32_subtract(&render_region, options->clip, &inner_region); - pixman_region32_fini(&inner_region); + pixman_region32_t clip_region; + if (options->clip) { + pixman_region32_init(&clip_region); + pixman_region32_copy(&clip_region, options->clip); + } else { + pixman_region32_init_rect(&clip_region, box.x, box.y, box.width, box.height); + } + pixman_region32_t window_region; + pixman_region32_init_rect(&window_region, window_box.x + options->window_corner_radius * 0.3, window_box.y + options->window_corner_radius * 0.3, + window_box.width - options->window_corner_radius * 0.6, window_box.height - options->window_corner_radius * 0.6); + pixman_region32_subtract(&clip_region, &clip_region, &window_region); + pixman_region32_fini(&window_region); push_fx_debug(renderer); - // blending will practically always be needed (unless we have a madman // who uses opaque shadows with zero sigma), so just enable it setup_blending(WLR_RENDER_BLEND_MODE_PREMULTIPLIED); @@ -482,17 +479,18 @@ void fx_render_pass_add_box_shadow(struct fx_gles_render_pass *pass, glUseProgram(renderer->shaders.box_shadow.program); - set_proj_matrix(renderer->shaders.box_shadow.proj, pass->projection_matrix, &shadow_box); + const struct wlr_render_color *color = &options->color; + set_proj_matrix(renderer->shaders.box_shadow.proj, pass->projection_matrix, &box); glUniform4f(renderer->shaders.box_shadow.color, color->r, color->g, color->b, color->a); - glUniform1f(renderer->shaders.box_shadow.blur_sigma, shadow_data->blur_sigma); + glUniform1f(renderer->shaders.box_shadow.blur_sigma, options->blur_sigma); glUniform1f(renderer->shaders.box_shadow.corner_radius, options->corner_radius); - glUniform2f(renderer->shaders.box_shadow.size, shadow_box.width, shadow_box.height); - glUniform2f(renderer->shaders.box_shadow.offset, options->shadow_data->offset_x, options->shadow_data->offset_y); - glUniform2f(renderer->shaders.box_shadow.position, shadow_box.x, shadow_box.y); + glUniform2f(renderer->shaders.box_shadow.size, box.width, box.height); + glUniform2f(renderer->shaders.box_shadow.position, box.x, box.y); + glUniform1f(renderer->shaders.box_shadow.window_corner_radius, options->window_corner_radius); + glUniform2f(renderer->shaders.box_shadow.window_half_size, window_box.width / 2.0, window_box.height / 2.0); + glUniform2f(renderer->shaders.box_shadow.window_position, window_box.x, window_box.y); - // TODO: also account for options->clip - render(&shadow_box, &render_region, renderer->shaders.box_shadow.pos_attrib); - pixman_region32_fini(&render_region); + render(&box, &clip_region, renderer->shaders.box_shadow.pos_attrib); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); diff --git a/render/fx_renderer/gles2/shaders/box_shadow.frag b/render/fx_renderer/gles2/shaders/box_shadow.frag index 1980434..ff8ac74 100644 --- a/render/fx_renderer/gles2/shaders/box_shadow.frag +++ b/render/fx_renderer/gles2/shaders/box_shadow.frag @@ -11,9 +11,11 @@ varying vec2 v_texcoord; uniform vec2 position; uniform vec2 size; -uniform vec2 offset; uniform float blur_sigma; uniform float corner_radius; +uniform vec2 window_position; +uniform vec2 window_half_size; +uniform float window_corner_radius; float gaussian(float x, float sigma) { const float pi = 3.141592653589793; @@ -80,8 +82,8 @@ void main() { // dither the alpha to break up color bands shadow_alpha += (random() - 0.5) / 128.0; - // get the window alpha so we can render around the window (fix pixel gap by adding 0.5 to radius) - float window_alpha = 1.0 - smoothstep(-1.0, 1.0, roundRectSDF((size * 0.5) - blur_sigma, position + blur_sigma, corner_radius + 0.5)); + // get the window alpha so we can render around the window (fix pixel gap by adding 1.0 to radius) + float window_alpha = smoothstep(-1.0, 1.0, roundRectSDF(window_half_size, window_position, window_corner_radius + 1.0)); - gl_FragColor = vec4(v_color.rgb, shadow_alpha) * (1.0 - window_alpha); + gl_FragColor = vec4(v_color.rgb, shadow_alpha) * window_alpha; } diff --git a/render/fx_renderer/shaders.c b/render/fx_renderer/shaders.c index 2c2aa7e..3d5d565 100644 --- a/render/fx_renderer/shaders.c +++ b/render/fx_renderer/shaders.c @@ -196,9 +196,11 @@ bool link_box_shadow_program(struct box_shadow_shader *shader) { shader->pos_attrib = glGetAttribLocation(prog, "pos"); shader->position = glGetUniformLocation(prog, "position"); shader->size = glGetUniformLocation(prog, "size"); - shader->offset = glGetUniformLocation(prog, "offset"); shader->blur_sigma = glGetUniformLocation(prog, "blur_sigma"); shader->corner_radius = glGetUniformLocation(prog, "corner_radius"); + shader->window_position = glGetUniformLocation(prog, "window_position"); + shader->window_half_size = glGetUniformLocation(prog, "window_half_size"); + shader->window_corner_radius = glGetUniformLocation(prog, "window_corner_radius"); return true; } |