diff --git a/include/render/fx_renderer/fx_renderer.h b/include/render/fx_renderer/fx_renderer.h index b9b9e0b..d46756c 100644 --- a/include/render/fx_renderer/fx_renderer.h +++ b/include/render/fx_renderer/fx_renderer.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -50,7 +51,8 @@ struct fx_framebuffer { /** Should only be used with custom fbs */ void fx_framebuffer_get_or_create_custom(struct fx_renderer *fx_renderer, - struct wlr_output *output, struct fx_framebuffer **fx_buffer); + struct wlr_output *output, struct wlr_swapchain *swapchain, + struct fx_framebuffer **fx_buffer); struct fx_framebuffer *fx_framebuffer_get_or_create(struct fx_renderer *renderer, struct wlr_buffer *wlr_buffer); @@ -176,15 +178,7 @@ struct fx_renderer { struct quad_shader quad; struct quad_grad_shader quad_grad; struct quad_round_shader quad_round; - struct quad_round_shader quad_round_tl; - struct quad_round_shader quad_round_tr; - struct quad_round_shader quad_round_bl; - struct quad_round_shader quad_round_br; struct quad_grad_round_shader quad_grad_round; - struct quad_grad_round_shader quad_grad_round_tl; - struct quad_grad_round_shader quad_grad_round_tr; - struct quad_grad_round_shader quad_grad_round_bl; - struct quad_grad_round_shader quad_grad_round_br; struct tex_shader tex_rgba; struct tex_shader tex_rgbx; struct tex_shader tex_ext; diff --git a/include/render/fx_renderer/shaders.h b/include/render/fx_renderer/shaders.h index 9800122..da50870 100644 --- a/include/render/fx_renderer/shaders.h +++ b/include/render/fx_renderer/shaders.h @@ -20,14 +20,6 @@ enum fx_tex_shader_source { SHADER_SOURCE_TEXTURE_EXTERNAL = 3, }; -enum fx_rounded_quad_shader_source { - SHADER_SOURCE_QUAD_ROUND = 1, - SHADER_SOURCE_QUAD_ROUND_TOP_LEFT = 2, - SHADER_SOURCE_QUAD_ROUND_TOP_RIGHT = 3, - SHADER_SOURCE_QUAD_ROUND_BOTTOM_RIGHT = 4, - SHADER_SOURCE_QUAD_ROUND_BOTTOM_LEFT = 5, -}; - struct quad_shader { GLuint program; GLint proj; @@ -67,9 +59,14 @@ struct quad_round_shader { GLint window_half_size; GLint window_position; GLint window_radius; + + GLint round_top_left; + GLint round_top_right; + GLint round_bottom_left; + GLint round_bottom_right; }; -bool link_quad_round_program(struct quad_round_shader *shader, enum fx_rounded_quad_shader_source source); +bool link_quad_round_program(struct quad_round_shader *shader); struct quad_grad_round_shader { GLuint program; @@ -89,10 +86,15 @@ struct quad_grad_round_shader { GLint count; GLint blend; + GLint round_top_left; + GLint round_top_right; + GLint round_bottom_left; + GLint round_bottom_right; + int max_len; }; -bool link_quad_grad_round_program(struct quad_grad_round_shader *shader, enum fx_rounded_quad_shader_source source, int max_len); +bool link_quad_grad_round_program(struct quad_grad_round_shader *shader, int max_len); struct tex_shader { GLuint program; @@ -107,6 +109,7 @@ struct tex_shader { GLint discard_transparent; GLint dim; GLint dim_color; + GLint round_top_left; GLint round_top_right; GLint round_bottom_left; diff --git a/include/scenefx/render/fx_renderer/fx_renderer.h b/include/scenefx/render/fx_renderer/fx_renderer.h index 5b43c4d..cbd312d 100644 --- a/include/scenefx/render/fx_renderer/fx_renderer.h +++ b/include/scenefx/render/fx_renderer/fx_renderer.h @@ -12,8 +12,7 @@ struct fx_renderer; struct wlr_renderer *fx_renderer_create_with_drm_fd(int drm_fd); struct wlr_renderer *fx_renderer_create(struct wlr_backend *backend); -struct fx_renderer *fx_get_renderer( - struct wlr_renderer *wlr_renderer); +struct fx_renderer *fx_get_renderer(struct wlr_renderer *wlr_renderer); bool fx_renderer_check_ext(struct wlr_renderer *renderer, const char *ext); GLuint fx_renderer_get_buffer_fbo(struct wlr_renderer *renderer, struct wlr_buffer *buffer); diff --git a/include/scenefx/render/pass.h b/include/scenefx/render/pass.h index 816174d..9da8259 100644 --- a/include/scenefx/render/pass.h +++ b/include/scenefx/render/pass.h @@ -4,6 +4,7 @@ #include #include #include +#include #include "render/egl.h" #include "scenefx/types/fx/corner_location.h" @@ -18,6 +19,12 @@ struct fx_gles_render_pass { struct fx_render_timer *timer; }; +struct fx_buffer_pass_options { + const struct wlr_buffer_pass_options *base; + + struct wlr_swapchain *swapchain; +}; + /** * Begin a new render pass with the supplied destination buffer. * @@ -26,7 +33,7 @@ struct fx_gles_render_pass { */ 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); + const struct fx_buffer_pass_options *options); struct fx_gradient { float degree; @@ -65,7 +72,7 @@ struct fx_render_rect_grad_options { struct fx_render_rounded_rect_options { struct wlr_render_rect_options base; int corner_radius; - enum corner_location corner_location; + enum corner_location corners; struct wlr_box window_box; int window_corner_radius; @@ -75,7 +82,7 @@ struct fx_render_rounded_rect_grad_options { struct wlr_render_rect_options base; struct fx_gradient gradient; int corner_radius; - enum corner_location corner_location; + enum corner_location corners; }; struct fx_render_box_shadow_options { diff --git a/include/scenefx/types/wlr_scene.h b/include/scenefx/types/wlr_scene.h index 2bbc770..19ab286 100644 --- a/include/scenefx/types/wlr_scene.h +++ b/include/scenefx/types/wlr_scene.h @@ -144,6 +144,7 @@ struct wlr_scene_rect { int width, height; float color[4]; int corner_radius; + enum corner_location corners; }; /** A scene-graph node displaying a shadow */ @@ -413,8 +414,8 @@ void wlr_scene_rect_set_size(struct wlr_scene_rect *rect, int width, int height) /** * Change the corner radius of an existing rectangle node. */ -void wlr_scene_rect_set_corner_radius(struct wlr_scene_rect *rect, int corner_radius); - +void wlr_scene_rect_set_corner_radius(struct wlr_scene_rect *rect, int corner_radius, + enum corner_location corners); /** * Change the color of an existing rectangle node. diff --git a/meson.build b/meson.build index bf8b7e8..bc7a67b 100644 --- a/meson.build +++ b/meson.build @@ -174,7 +174,6 @@ pkgconfig.generate( name: versioned_name, version: meson.project_version(), filebase: meson.project_name(), - name: meson.project_name(), description: 'Wlroots effects library', subdirs: versioned_name, ) diff --git a/render/fx_renderer/fx_framebuffer.c b/render/fx_renderer/fx_framebuffer.c index dd4b299..b03f2ed 100644 --- a/render/fx_renderer/fx_framebuffer.c +++ b/render/fx_renderer/fx_framebuffer.c @@ -69,14 +69,20 @@ GLuint fx_framebuffer_get_fbo(struct fx_framebuffer *buffer) { } void fx_framebuffer_get_or_create_custom(struct fx_renderer *renderer, - struct wlr_output *output, struct fx_framebuffer **fx_framebuffer) { + struct wlr_output *output, struct wlr_swapchain *swapchain, + struct fx_framebuffer **fx_framebuffer) { struct wlr_allocator *allocator = output->allocator; - struct wlr_swapchain *swapchain = output->swapchain; + if (!swapchain) { + swapchain = output->swapchain; + } int width = output->width; int height = output->height; struct wlr_buffer *wlr_buffer = NULL; if (*fx_framebuffer == NULL) { + if (swapchain == NULL) { + printf("swapchain is null\n"); + } wlr_buffer = wlr_allocator_create_buffer(allocator, width, height, &swapchain->format); if (wlr_buffer == NULL) { @@ -170,3 +176,4 @@ void fx_framebuffer_destroy(struct fx_framebuffer *fx_buffer) { free(fx_buffer); } + diff --git a/render/fx_renderer/fx_pass.c b/render/fx_renderer/fx_pass.c index 8788255..c600b10 100644 --- a/render/fx_renderer/fx_pass.c +++ b/render/fx_renderer/fx_pass.c @@ -12,6 +12,7 @@ #include "render/egl.h" #include "render/fx_renderer/fx_renderer.h" #include "render/fx_renderer/matrix.h" +#include "render/fx_renderer/shaders.h" #include "render/pass.h" #include "scenefx/render/fx_renderer/fx_renderer.h" #include "scenefx/render/fx_renderer/fx_effect_framebuffers.h" @@ -244,23 +245,9 @@ static void setup_blending(enum wlr_render_blend_mode mode) { } } -// make sure the texture source box does not try and sample outside of the -// texture -static void check_tex_src_box(const struct wlr_render_texture_options *options) { - if (!wlr_fbox_empty(&options->src_box)) { - const struct wlr_fbox *box = &options->src_box; - assert(box->x >= 0 && box->y >= 0 && - box->x + box->width <= options->texture->width && - box->y + box->height <= options->texture->height); - } -} - void fx_render_pass_add_texture(struct fx_gles_render_pass *pass, const struct fx_render_texture_options *fx_options) { const struct wlr_render_texture_options *options = &fx_options->base; - - check_tex_src_box(options); - struct fx_renderer *renderer = pass->buffer->renderer; struct fx_texture *texture = fx_get_texture(options->texture); @@ -424,28 +411,6 @@ void fx_render_pass_add_rounded_rect(struct fx_gles_render_pass *pass, struct fx_renderer *renderer = pass->buffer->renderer; - struct quad_round_shader *shader = NULL; - switch (fx_options->corner_location) { - case CORNER_LOCATION_ALL: - shader = &renderer->shaders.quad_round; - break; - case CORNER_LOCATION_TOP_LEFT: - shader = &renderer->shaders.quad_round_tl; - break; - case CORNER_LOCATION_TOP_RIGHT: - shader = &renderer->shaders.quad_round_tr; - break; - case CORNER_LOCATION_BOTTOM_LEFT: - shader = &renderer->shaders.quad_round_bl; - break; - case CORNER_LOCATION_BOTTOM_RIGHT: - shader = &renderer->shaders.quad_round_br; - break; - default: - wlr_log(WLR_ERROR, "Invalid Corner Location. Aborting render"); - abort(); - } - const struct wlr_render_color *color = &options->color; pixman_region32_t clip_region; @@ -472,19 +437,29 @@ void fx_render_pass_add_rounded_rect(struct fx_gles_render_pass *pass, setup_blending(WLR_RENDER_BLEND_MODE_PREMULTIPLIED); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glUseProgram(shader->program); - - set_proj_matrix(shader->proj, pass->projection_matrix, &box); - glUniform4f(shader->color, color->r, color->g, color->b, color->a); + struct quad_round_shader shader = renderer->shaders.quad_round; - glUniform2f(shader->size, box.width, box.height); - glUniform2f(shader->position, box.x, box.y); - glUniform1f(shader->radius, fx_options->corner_radius); - glUniform2f(shader->window_half_size, window_box.width / 2.0, window_box.height / 2.0); - glUniform2f(shader->window_position, window_box.x, window_box.y); - glUniform1f(shader->window_radius, fx_options->window_corner_radius); + glUseProgram(shader.program); - render(&box, &clip_region, shader->pos_attrib); + set_proj_matrix(shader.proj, pass->projection_matrix, &box); + glUniform4f(shader.color, color->r, color->g, color->b, color->a); + + glUniform2f(shader.size, box.width, box.height); + glUniform2f(shader.position, box.x, box.y); + glUniform1f(shader.radius, fx_options->corner_radius); + glUniform2f(shader.window_half_size, window_box.width / 2.0, window_box.height / 2.0); + glUniform2f(shader.window_position, window_box.x, window_box.y); + glUniform1f(shader.window_radius, fx_options->window_corner_radius); + glUniform1f(shader.round_top_left, + (CORNER_LOCATION_TOP_LEFT & fx_options->corners) == CORNER_LOCATION_TOP_LEFT); + glUniform1f(shader.round_top_right, + (CORNER_LOCATION_TOP_RIGHT & fx_options->corners) == CORNER_LOCATION_TOP_RIGHT); + glUniform1f(shader.round_bottom_left, + (CORNER_LOCATION_BOTTOM_LEFT & fx_options->corners) == CORNER_LOCATION_BOTTOM_LEFT); + glUniform1f(shader.round_bottom_right, + (CORNER_LOCATION_BOTTOM_RIGHT & fx_options->corners) == CORNER_LOCATION_BOTTOM_RIGHT); + + render(&box, &clip_region, renderer->shaders.quad_round.pos_attrib); pixman_region32_fini(&clip_region); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); @@ -497,37 +472,9 @@ void fx_render_pass_add_rounded_rect_grad(struct fx_gles_render_pass *pass, struct fx_renderer *renderer = pass->buffer->renderer; - struct quad_grad_round_shader *shader = NULL; - enum fx_rounded_quad_shader_source corner; - switch (fx_options->corner_location) { - case CORNER_LOCATION_ALL: - corner = SHADER_SOURCE_QUAD_ROUND; - shader = &renderer->shaders.quad_grad_round; - break; - case CORNER_LOCATION_TOP_LEFT: - corner = SHADER_SOURCE_QUAD_ROUND_TOP_LEFT; - shader = &renderer->shaders.quad_grad_round_tl; - break; - case CORNER_LOCATION_TOP_RIGHT: - corner = SHADER_SOURCE_QUAD_ROUND_TOP_RIGHT; - shader = &renderer->shaders.quad_grad_round_tr; - break; - case CORNER_LOCATION_BOTTOM_LEFT: - corner = SHADER_SOURCE_QUAD_ROUND_BOTTOM_LEFT; - shader = &renderer->shaders.quad_grad_round_bl; - break; - case CORNER_LOCATION_BOTTOM_RIGHT: - corner = SHADER_SOURCE_QUAD_ROUND_TOP_RIGHT; - shader = &renderer->shaders.quad_grad_round_br; - break; - default: - wlr_log(WLR_ERROR, "Invalid Corner Location. Aborting render"); - abort(); - } - - if (shader->max_len <= fx_options->gradient.count) { - glDeleteProgram(shader->program); - if (!link_quad_grad_round_program(shader, corner, fx_options->gradient.count + 1)) { + if (renderer->shaders.quad_grad_round.max_len <= fx_options->gradient.count) { + glDeleteProgram(renderer->shaders.quad_grad_round.program); + if (!link_quad_grad_round_program(&renderer->shaders.quad_grad_round, fx_options->gradient.count + 1)) { wlr_log(WLR_ERROR, "Could not link quad shader after updating max_len to %d. Aborting renderer", fx_options->gradient.count + 1); abort(); } @@ -539,24 +486,34 @@ void fx_render_pass_add_rounded_rect_grad(struct fx_gles_render_pass *pass, push_fx_debug(renderer); setup_blending(WLR_RENDER_BLEND_MODE_PREMULTIPLIED); - glUseProgram(shader->program); + struct quad_grad_round_shader shader = renderer->shaders.quad_grad_round; + glUseProgram(shader.program); - set_proj_matrix(shader->proj, pass->projection_matrix, &box); + set_proj_matrix(shader.proj, pass->projection_matrix, &box); - glUniform2f(shader->size, box.width, box.height); - glUniform2f(shader->position, box.x, box.y); - glUniform1f(shader->radius, fx_options->corner_radius); + glUniform2f(shader.size, box.width, box.height); + glUniform2f(shader.position, box.x, box.y); + glUniform1f(shader.radius, fx_options->corner_radius); - glUniform4fv(shader->colors, fx_options->gradient.count, (GLfloat*)fx_options->gradient.colors); - glUniform1i(shader->count, fx_options->gradient.count); - glUniform2f(shader->grad_size, fx_options->gradient.range.width, fx_options->gradient.range.height); - glUniform1f(shader->degree, fx_options->gradient.degree); - glUniform1f(shader->linear, fx_options->gradient.linear); - glUniform1f(shader->blend, fx_options->gradient.blend); - glUniform2f(shader->grad_box, fx_options->gradient.range.x, fx_options->gradient.range.y); - glUniform2f(shader->origin, fx_options->gradient.origin[0], fx_options->gradient.origin[1]); + glUniform4fv(shader.colors, fx_options->gradient.count, (GLfloat*)fx_options->gradient.colors); + glUniform1i(shader.count, fx_options->gradient.count); + glUniform2f(shader.grad_size, fx_options->gradient.range.width, fx_options->gradient.range.height); + glUniform1f(shader.degree, fx_options->gradient.degree); + glUniform1f(shader.linear, fx_options->gradient.linear); + glUniform1f(shader.blend, fx_options->gradient.blend); + glUniform2f(shader.grad_box, fx_options->gradient.range.x, fx_options->gradient.range.y); + glUniform2f(shader.origin, fx_options->gradient.origin[0], fx_options->gradient.origin[1]); - render(&box, options->clip, shader->pos_attrib); + glUniform1f(shader.round_top_left, + (CORNER_LOCATION_TOP_LEFT & fx_options->corners) == CORNER_LOCATION_TOP_LEFT); + glUniform1f(shader.round_top_right, + (CORNER_LOCATION_TOP_RIGHT & fx_options->corners) == CORNER_LOCATION_TOP_RIGHT); + glUniform1f(shader.round_bottom_left, + (CORNER_LOCATION_BOTTOM_LEFT & fx_options->corners) == CORNER_LOCATION_BOTTOM_LEFT); + glUniform1f(shader.round_bottom_right, + (CORNER_LOCATION_BOTTOM_RIGHT & fx_options->corners) == CORNER_LOCATION_BOTTOM_RIGHT); + + render(&box, options->clip, shader.pos_attrib); pop_fx_debug(renderer); } @@ -634,8 +591,6 @@ static void render_blur_segments(struct fx_gles_render_pass *pass, fx_options->current_buffer->buffer); struct fx_texture *texture = fx_get_texture(options->texture); - check_tex_src_box(options); - /* * Render */ @@ -703,9 +658,6 @@ static void render_blur_effects(struct fx_gles_render_pass *pass, struct fx_render_blur_pass_options *fx_options) { struct fx_render_texture_options *tex_options = &fx_options->tex_options; struct wlr_render_texture_options *options = &tex_options->base; - - check_tex_src_box(options); - struct fx_renderer *renderer = pass->buffer->renderer; struct blur_data *blur_data = fx_options->blur_data; struct fx_texture *texture = fx_get_texture(options->texture); @@ -926,7 +878,7 @@ void fx_render_pass_add_optimized_blur(struct fx_gles_render_pass *pass, struct fx_framebuffer *buffer = get_main_buffer_blur(pass, &blur_options); // Update the optimized blur buffer if invalid - fx_framebuffer_get_or_create_custom(renderer, pass->output, + fx_framebuffer_get_or_create_custom(renderer, pass->output, NULL, &pass->fx_effect_framebuffers->optimized_blur_buffer); // Render the newly blurred content into the blur_buffer @@ -1051,7 +1003,8 @@ static struct fx_gles_render_pass *begin_buffer_pass(struct fx_framebuffer *buff 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 wlr_output *output, const struct fx_buffer_pass_options *fx_options) { + const struct wlr_buffer_pass_options *options = fx_options->base; struct fx_renderer *renderer = fx_get_renderer(wlr_renderer); renderer->basic_renderer = (output == NULL); @@ -1077,9 +1030,12 @@ struct fx_gles_render_pass *fx_renderer_begin_buffer_pass( // Update the buffers if needed if (!renderer->basic_renderer) { fbos = fx_effect_framebuffers_try_get(output); - fx_framebuffer_get_or_create_custom(renderer, output, &fbos->blur_saved_pixels_buffer); - fx_framebuffer_get_or_create_custom(renderer, output, &fbos->effects_buffer); - fx_framebuffer_get_or_create_custom(renderer, output, &fbos->effects_buffer_swapped); + fx_framebuffer_get_or_create_custom(renderer, output, fx_options->swapchain, + &fbos->blur_saved_pixels_buffer); + fx_framebuffer_get_or_create_custom(renderer, output, fx_options->swapchain, + &fbos->effects_buffer); + fx_framebuffer_get_or_create_custom(renderer, output, fx_options->swapchain, + &fbos->effects_buffer_swapped); pixman_region32_init(&fbos->blur_padding_region); } diff --git a/render/fx_renderer/fx_renderer.c b/render/fx_renderer/fx_renderer.c index 7029192..d929c4f 100644 --- a/render/fx_renderer/fx_renderer.c +++ b/render/fx_renderer/fx_renderer.c @@ -121,7 +121,10 @@ 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, NULL, options); + fx_renderer_begin_buffer_pass(wlr_renderer, wlr_buffer, NULL, &(struct fx_buffer_pass_options) { + .base = options, + .swapchain = NULL, + }); if (!pass) { return NULL; } @@ -314,59 +317,17 @@ static bool link_shaders(struct fx_renderer *renderer) { // quad fragment shader with gradients if (!link_quad_grad_program(&renderer->shaders.quad_grad, 16)) { - wlr_log(WLR_ERROR, "Could not link quad shader"); + wlr_log(WLR_ERROR, "Could not link quad grad shader"); goto error; } - // rounded quad fragment shaders - if (!link_quad_grad_round_program(&renderer->shaders.quad_grad_round, SHADER_SOURCE_QUAD_ROUND, 16)) { - wlr_log(WLR_ERROR, "Could not link quad shader"); - goto error; - } - // rounded quad fragment shaders - if (!link_quad_grad_round_program(&renderer->shaders.quad_grad_round_tl, SHADER_SOURCE_QUAD_ROUND_TOP_LEFT, 16)) { - wlr_log(WLR_ERROR, "Could not link quad shader"); - goto error; - } - // rounded quad fragment shaders - if (!link_quad_grad_round_program(&renderer->shaders.quad_grad_round_tr, SHADER_SOURCE_QUAD_ROUND_TOP_RIGHT, 16)) { - wlr_log(WLR_ERROR, "Could not link quad shader"); - goto error; - } - // rounded quad fragment shaders - if (!link_quad_grad_round_program(&renderer->shaders.quad_grad_round_bl, SHADER_SOURCE_QUAD_ROUND_BOTTOM_LEFT, 16)) { - wlr_log(WLR_ERROR, "Could not link quad shader"); - goto error; - } - // rounded quad fragment shaders - if (!link_quad_grad_round_program(&renderer->shaders.quad_grad_round_br, SHADER_SOURCE_QUAD_ROUND_BOTTOM_RIGHT, 16)) { - wlr_log(WLR_ERROR, "Could not link quad shader"); + if (!link_quad_grad_round_program(&renderer->shaders.quad_grad_round, 16)) { + wlr_log(WLR_ERROR, "Could not link quad grad round shader"); goto error; } - // rounded quad fragment shaders - if (!link_quad_round_program(&renderer->shaders.quad_round, SHADER_SOURCE_QUAD_ROUND)) { - wlr_log(WLR_ERROR, "Could not link quad shader"); - goto error; - } - // rounded quad fragment shaders - if (!link_quad_round_program(&renderer->shaders.quad_round_tl, SHADER_SOURCE_QUAD_ROUND_TOP_LEFT)) { - wlr_log(WLR_ERROR, "Could not link quad shader"); - goto error; - } - // rounded quad fragment shaders - if (!link_quad_round_program(&renderer->shaders.quad_round_tr, SHADER_SOURCE_QUAD_ROUND_TOP_RIGHT)) { - wlr_log(WLR_ERROR, "Could not link quad shader"); - goto error; - } - // rounded quad fragment shaders - if (!link_quad_round_program(&renderer->shaders.quad_round_bl, SHADER_SOURCE_QUAD_ROUND_BOTTOM_LEFT)) { - wlr_log(WLR_ERROR, "Could not link quad shader"); - goto error; - } - // rounded quad fragment shaders - if (!link_quad_round_program(&renderer->shaders.quad_round_br, SHADER_SOURCE_QUAD_ROUND_BOTTOM_RIGHT)) { - wlr_log(WLR_ERROR, "Could not link quad shader"); + if (!link_quad_round_program(&renderer->shaders.quad_round)) { + wlr_log(WLR_ERROR, "Could not link quad round shader"); goto error; } @@ -409,16 +370,8 @@ static bool link_shaders(struct fx_renderer *renderer) { error: glDeleteProgram(renderer->shaders.quad.program); glDeleteProgram(renderer->shaders.quad_round.program); - glDeleteProgram(renderer->shaders.quad_round_tl.program); - glDeleteProgram(renderer->shaders.quad_round_tr.program); - glDeleteProgram(renderer->shaders.quad_round_bl.program); - glDeleteProgram(renderer->shaders.quad_round_br.program); glDeleteProgram(renderer->shaders.quad_grad.program); glDeleteProgram(renderer->shaders.quad_grad_round.program); - glDeleteProgram(renderer->shaders.quad_grad_round_tl.program); - glDeleteProgram(renderer->shaders.quad_grad_round_tr.program); - glDeleteProgram(renderer->shaders.quad_grad_round_bl.program); - glDeleteProgram(renderer->shaders.quad_grad_round_br.program); glDeleteProgram(renderer->shaders.tex_rgba.program); glDeleteProgram(renderer->shaders.tex_rgbx.program); glDeleteProgram(renderer->shaders.tex_ext.program); @@ -565,6 +518,7 @@ struct wlr_renderer *fx_renderer_create_egl(struct wlr_egl *egl) { wlr_egl_unset_current(renderer->egl); get_fx_shm_formats(renderer, &renderer->shm_texture_formats); + printf("made renderer\n"); return &renderer->wlr_renderer; diff --git a/render/fx_renderer/gles2/shaders/quad_grad_round.frag b/render/fx_renderer/gles2/shaders/quad_grad_round.frag index e8335e4..639461b 100644 --- a/render/fx_renderer/gles2/shaders/quad_grad_round.frag +++ b/render/fx_renderer/gles2/shaders/quad_grad_round.frag @@ -1,13 +1,3 @@ -#define SOURCE_QUAD_ROUND 1 -#define SOURCE_QUAD_ROUND_TOP_LEFT 2 -#define SOURCE_QUAD_ROUND_TOP_RIGHT 3 -#define SOURCE_QUAD_ROUND_BOTTOM_RIGHT 4 -#define SOURCE_QUAD_ROUND_BOTTOM_LEFT 5 - -#if !defined(SOURCE) -#error "Missing shader preamble" -#endif - precision mediump float; varying vec4 v_color; varying vec2 v_texcoord; @@ -25,27 +15,20 @@ uniform bool linear; uniform bool blend; uniform int count; -vec2 getCornerDist() { -#if SOURCE == SOURCE_QUAD_ROUND - vec2 half_size = size * 0.5; - return abs(gl_FragCoord.xy - position - half_size) - half_size + radius; -#elif SOURCE == SOURCE_QUAD_ROUND_TOP_LEFT - return abs(gl_FragCoord.xy - position - size) - size + radius; -#elif SOURCE == SOURCE_QUAD_ROUND_TOP_RIGHT - return abs(gl_FragCoord.xy - position - vec2(0, size.y)) - size + radius; -#elif SOURCE == SOURCE_QUAD_ROUND_BOTTOM_RIGHT - return abs(gl_FragCoord.xy - position) - size + radius; -#elif SOURCE == SOURCE_QUAD_ROUND_BOTTOM_LEFT - return abs(gl_FragCoord.xy - position - vec2(size.x, 0)) - size + radius; -#endif -} +uniform bool round_top_left; +uniform bool round_top_right; +uniform bool round_bottom_left; +uniform bool round_bottom_right; vec4 gradient(vec4 colors[LEN], int count, vec2 size, vec2 grad_box, vec2 origin, float degree, bool linear, bool blend); +float corner_alpha(vec2 size, vec2 position, float radius, + bool round_tl, bool round_tr, bool round_bl, bool round_br); + +// TODO: void main() { - vec2 q = getCornerDist(); - float dist = min(max(q.x,q.y), 0.0) + length(max(q, 0.0)) - radius; - float smoothedAlpha = 1.0 - smoothstep(-1.0, 0.5, dist); + float rect_alpha = v_color.a * corner_alpha(size, position, radius, + round_top_left, round_top_right, round_bottom_left, round_bottom_right); - gl_FragColor = mix(vec4(0), gradient(colors, count, size, grad_box, origin, degree, linear, blend), smoothedAlpha); + gl_FragColor = mix(vec4(0), gradient(colors, count, size, grad_box, origin, degree, linear, blend), rect_alpha); } diff --git a/render/fx_renderer/gles2/shaders/quad_round.frag b/render/fx_renderer/gles2/shaders/quad_round.frag index 72972ec..f1c0dd6 100644 --- a/render/fx_renderer/gles2/shaders/quad_round.frag +++ b/render/fx_renderer/gles2/shaders/quad_round.frag @@ -1,13 +1,3 @@ -#define SOURCE_QUAD_ROUND 1 -#define SOURCE_QUAD_ROUND_TOP_LEFT 2 -#define SOURCE_QUAD_ROUND_TOP_RIGHT 3 -#define SOURCE_QUAD_ROUND_BOTTOM_RIGHT 4 -#define SOURCE_QUAD_ROUND_BOTTOM_LEFT 5 - -#if !defined(SOURCE) -#error "Missing shader preamble" -#endif - precision mediump float; varying vec4 v_color; varying vec2 v_texcoord; @@ -20,30 +10,18 @@ uniform vec2 window_half_size; uniform vec2 window_position; uniform float window_radius; -// TODO: use the corner_mask from the tex shader with roundRectSDF -vec2 getCornerDist() { -#if SOURCE == SOURCE_QUAD_ROUND - vec2 half_size = size * 0.5; - return abs(gl_FragCoord.xy - position - half_size) - half_size + radius; -#elif SOURCE == SOURCE_QUAD_ROUND_TOP_LEFT - return abs(gl_FragCoord.xy - position - size) - size + radius; -#elif SOURCE == SOURCE_QUAD_ROUND_TOP_RIGHT - return abs(gl_FragCoord.xy - position - vec2(0, size.y)) - size + radius; -#elif SOURCE == SOURCE_QUAD_ROUND_BOTTOM_RIGHT - return abs(gl_FragCoord.xy - position) - size + radius; -#elif SOURCE == SOURCE_QUAD_ROUND_BOTTOM_LEFT - return abs(gl_FragCoord.xy - position - vec2(size.x, 0)) - size + radius; -#endif -} +uniform bool round_top_left; +uniform bool round_top_right; +uniform bool round_bottom_left; +uniform bool round_bottom_right; -float roundRectSDF(vec2 half_size, vec2 position, float radius); +float corner_alpha(vec2 size, vec2 position, float radius, + bool round_tl, bool round_tr, bool round_bl, bool round_br); void main() { - vec2 q = getCornerDist(); - float dist = min(max(q.x,q.y), 0.0) + length(max(q, 0.0)) - radius; - float rect_alpha = v_color.a * 1.0 - smoothstep(-1.0, 1.0, dist); - - float window_alpha = smoothstep(-1.0, 1.0, roundRectSDF(window_half_size, window_position, window_radius + 1.0)); // pull in radius by 1.0 px + float corner_alpha = corner_alpha(size, position, radius, + round_top_left, round_top_right, round_bottom_left, round_bottom_right); + float window_alpha = 1.0; // TODO: smoothstep(-1.0, 1.0, roundRectSDF(window_half_size, window_position, window_radius + 1.0)); // pull in radius by 1.0 px - gl_FragColor = vec4(v_color.rgb, rect_alpha) * window_alpha; + gl_FragColor = mix(v_color, vec4(0.0), corner_alpha) * window_alpha; } diff --git a/render/fx_renderer/shaders.c b/render/fx_renderer/shaders.c index f9e13d3..3473568 100644 --- a/render/fx_renderer/shaders.c +++ b/render/fx_renderer/shaders.c @@ -145,10 +145,10 @@ bool link_quad_grad_program(struct quad_grad_shader *shader, int max_len) { return true; } -bool link_quad_round_program(struct quad_round_shader *shader, enum fx_rounded_quad_shader_source source) { - GLchar quad_src[2048]; - snprintf(quad_src, sizeof(quad_src), - "#define SOURCE %d\n%s\n%s", source, quad_round_frag_src, round_rect_sdf_frag_src); +bool link_quad_round_program(struct quad_round_shader *shader) { + GLchar quad_src[4096]; + snprintf(quad_src, sizeof(quad_src), "%s\n%s\n%s", quad_round_frag_src, + corner_alpha_frag_src, round_rect_sdf_frag_src); GLuint prog; shader->program = prog = link_program(quad_src); @@ -166,13 +166,18 @@ bool link_quad_round_program(struct quad_round_shader *shader, enum fx_rounded_q shader->window_position = glGetUniformLocation(prog, "window_position"); shader->window_radius = glGetUniformLocation(prog, "window_radius"); + shader->round_top_left = glGetUniformLocation(prog, "round_top_left"); + shader->round_top_right = glGetUniformLocation(prog, "round_top_right"); + shader->round_bottom_left = glGetUniformLocation(prog, "round_bottom_left"); + shader->round_bottom_right = glGetUniformLocation(prog, "round_bottom_right"); + return true; } -bool link_quad_grad_round_program(struct quad_grad_round_shader *shader, enum fx_rounded_quad_shader_source source, int max_len) { +bool link_quad_grad_round_program(struct quad_grad_round_shader *shader, int max_len) { GLchar quad_src[4096]; - snprintf(quad_src, sizeof(quad_src), - "#define SOURCE %d\n#define LEN %d\n%s\n%s", source, max_len, quad_grad_round_frag_src, gradient_frag_src); + snprintf(quad_src, sizeof(quad_src), "#define LEN %d\n%s\n%s\n%s\n%s", max_len, quad_grad_round_frag_src, + gradient_frag_src, corner_alpha_frag_src, round_rect_sdf_frag_src); GLuint prog; shader->program = prog = link_program(quad_src); @@ -196,6 +201,11 @@ bool link_quad_grad_round_program(struct quad_grad_round_shader *shader, enum fx shader->count = glGetUniformLocation(prog, "count"); shader->blend = glGetUniformLocation(prog, "blend"); + shader->round_top_left = glGetUniformLocation(prog, "round_top_left"); + shader->round_top_right = glGetUniformLocation(prog, "round_top_right"); + shader->round_bottom_left = glGetUniformLocation(prog, "round_bottom_left"); + shader->round_bottom_right = glGetUniformLocation(prog, "round_bottom_right"); + shader->max_len = max_len; return true; diff --git a/tinywl/tinywl.c b/tinywl/tinywl.c index d0067b4..aa11af1 100644 --- a/tinywl/tinywl.c +++ b/tinywl/tinywl.c @@ -954,7 +954,8 @@ static void server_new_xdg_toplevel(struct wl_listener *listener, void *data) { toplevel->border = wlr_scene_rect_create(toplevel->scene_tree, 0, 0, (float[4]){ 1.0f, 0.f, 0.f, 1.0f }); - wlr_scene_rect_set_corner_radius(toplevel->border, toplevel->corner_radius + BORDER_THICKNESS); + wlr_scene_rect_set_corner_radius(toplevel->border, + toplevel->corner_radius + BORDER_THICKNESS, CORNER_LOCATION_ALL); wlr_scene_node_set_position(&toplevel->border->node, -BORDER_THICKNESS, -BORDER_THICKNESS); float blur_sigma = 20.0f; diff --git a/types/scene/wlr_scene.c b/types/scene/wlr_scene.c index bab2d00..b1272a2 100644 --- a/types/scene/wlr_scene.c +++ b/types/scene/wlr_scene.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -19,6 +20,7 @@ #include "scenefx/render/fx_renderer/fx_renderer.h" #include "scenefx/render/pass.h" #include "scenefx/types/fx/blur_data.h" +#include "scenefx/types/fx/corner_location.h" #include "types/wlr_buffer.h" #include "types/wlr_output.h" #include "types/wlr_scene.h" @@ -663,6 +665,7 @@ struct wlr_scene_rect *wlr_scene_rect_create(struct wlr_scene_tree *parent, scene_rect->height = height; memcpy(scene_rect->color, color, sizeof(scene_rect->color)); scene_rect->corner_radius = 0; + scene_rect->corners = CORNER_LOCATION_NONE; scene_node_update(&scene_rect->node, NULL); @@ -744,12 +747,14 @@ static void scene_buffer_set_texture(struct wlr_scene_buffer *scene_buffer, } } -void wlr_scene_rect_set_corner_radius(struct wlr_scene_rect *rect, int corner_radius) { - if (rect->corner_radius == corner_radius) { +void wlr_scene_rect_set_corner_radius(struct wlr_scene_rect *rect, int corner_radius, + enum corner_location corners) { + if (rect->corner_radius == corner_radius && rect->corners == corners) { return; } rect->corner_radius = corner_radius; + rect->corners = corners; scene_node_update(&rect->node, NULL); } @@ -842,6 +847,7 @@ struct wlr_scene_optimized_blur *wlr_scene_optimized_blur_create( void wlr_scene_optimized_blur_set_size(struct wlr_scene_optimized_blur *blur_node, int width, int height) { + assert(blur_node); if (blur_node->width == width && blur_node->height == height) { return; } @@ -1584,7 +1590,7 @@ static void scene_entry_render(struct render_list_entry *entry, const struct ren }, }; - if (scene_rect->corner_radius) { + if (scene_rect->corner_radius && scene_rect->corners != CORNER_LOCATION_NONE) { struct wlr_box window_box; int window_corner_radius; scene_get_next_sibling_geometry(node, &window_box, &window_corner_radius); @@ -1598,7 +1604,7 @@ static void scene_entry_render(struct render_list_entry *entry, const struct ren struct fx_render_rounded_rect_options rounded_rect_options = { .base = rect_options.base, .corner_radius = scene_rect->corner_radius, - .corner_location = CORNER_LOCATION_ALL, + .corners = scene_rect->corners, .window_box = window_box, .window_corner_radius = window_corner_radius, }; @@ -2423,9 +2429,12 @@ bool wlr_scene_output_build_state(struct wlr_scene_output *scene_output, struct fx_gles_render_pass *render_pass = fx_renderer_begin_buffer_pass(output->renderer, buffer, output, - &(struct wlr_buffer_pass_options) { - .timer = timer ? timer->render_timer : NULL, - .color_transform = options->color_transform, + &(struct fx_buffer_pass_options) { + .base = &(struct wlr_buffer_pass_options){ + .timer = timer ? timer->render_timer : NULL, + .color_transform = options->color_transform, + }, + .swapchain = swapchain, } ); if (render_pass == NULL) {