diff options
author | LuoYi | 2021-10-09 19:44:59 +0800 |
---|---|---|
committer | LuoYi | 2021-10-09 19:44:59 +0800 |
commit | 6828d3b1e8cb0b41e296c173e37030448c306ac4 (patch) | |
tree | 5400e37c5b6551a1e39e7de500a9b2efb9ff5058 /meta_clip_effect.c | |
parent | cf46f104d8acbe30108fb179b12f0e3c1e6c6440 (diff) | |
download | aur-6828d3b1e8cb0b41e296c173e37030448c306ac4.tar.gz |
try to integrate shell-blur-effect
Diffstat (limited to 'meta_clip_effect.c')
-rw-r--r-- | meta_clip_effect.c | 252 |
1 files changed, 66 insertions, 186 deletions
diff --git a/meta_clip_effect.c b/meta_clip_effect.c index 247af632f48d..5759d2f81d43 100644 --- a/meta_clip_effect.c +++ b/meta_clip_effect.c @@ -2,73 +2,16 @@ #include "meta_clip_effect.h" #include "meta/prefs.h" +#include "shader.h" typedef struct { CoglPipeline *pipeline; - CoglTexture *corner_texture; ClutterActor *actor; cairo_rectangle_int_t bounds; } MetaClipEffectPrivate; G_DEFINE_TYPE_WITH_PRIVATE(MetaClipEffect, meta_clip_effect, CLUTTER_TYPE_OFFSCREEN_EFFECT) -/* - * THIS shader copied from the kwin-plugin of CutefishOS project - * see https://github.com/cutefishos/kwin-plugins/blob/main/plugins/roundedwindow/roundedwindow.cpp - */ -#define ROUNDED_CLIP_FRAGMENT_SHADER_DECLARATIONS \ -"uniform vec2 corner_scale; \n"\ -"uniform vec2 offset_lt; // left top \n"\ -"uniform vec2 offset_rt; // right top \n"\ -"uniform vec2 offset_lb; // left bottom \n"\ -"uniform vec2 offset_rb; // right bottom \n"\ -"uniform vec4 bounds; \n"\ -"uniform float opacity; \n"\ -"uniform int skip; \n"\ -" \n"\ -"float cal_alpha(void) { \n"\ -" vec2 scale = corner_scale; \n"\ -" vec2 coord = cogl_tex_coord0_in.xy; \n"\ -" vec4 fg; \n"\ -" \n"\ -" if(coord.x < bounds.x || coord.y < bounds.y || \n"\ -" coord.x > bounds.z || coord.y > bounds.w) { \n"\ -" return 0.0; \n"\ -" } \n"\ -" \n"\ -" if(coord.x < 0.5) { \n"\ -" if(coord.y < 0.5) { \n"\ -" vec2 cornerCoord = vec2(coord.x * scale.x, coord.y * scale.y); \n"\ -" fg = texture2D(cogl_sampler1, cornerCoord - offset_lt); \n"\ -" } else { \n"\ -" vec2 cornerCoordBL = vec2(coord.x * scale.x, (1.0 - coord.y) * scale.y); \n"\ -" fg = texture2D(cogl_sampler1, cornerCoordBL - offset_lb); \n"\ -" } \n"\ -" } else { \n"\ -" if(coord.y < 0.5) { \n"\ -" vec2 cornerCoordTR = vec2((1.0 - coord.x) * scale.x, coord.y * scale.y); \n"\ -" fg = texture2D(cogl_sampler1, cornerCoordTR - offset_rt); \n"\ -" } else { \n"\ -" vec2 cornerCoordBR = vec2((1.0 - coord.x) * scale.x, (1.0 - coord.y) * scale.y); \n"\ -" fg = texture2D(cogl_sampler1, cornerCoordBR - offset_rb); \n"\ -" } \n"\ -" } \n"\ -" \n"\ -" return fg.r; \n"\ -"} \n" - -#define ROUNDED_CLIP_FRAGMENT_SHADER_CODE \ -"vec4 bg = texture2D(cogl_sampler0, cogl_tex_coord0_in.xy) * opacity; \n"\ -"if (skip == 1) \n"\ -" cogl_color_out = bg; \n"\ -"else \n"\ -" cogl_color_out = bg * cal_alpha(); \n" - -// "cogl_color_out = bg * 0.6 + (vec4(0.4) * cal_alpha()); // for_debug \n" - - - - static CoglPipeline * meta_clip_effect_class_create_pipeline(ClutterOffscreenEffect *effect, CoglTexture *texture) @@ -76,7 +19,6 @@ meta_clip_effect_class_create_pipeline(ClutterOffscreenEffect *effect, MetaClipEffect *clip_effect = META_CLIP_EFFECT (effect); MetaClipEffectPrivate *priv = meta_clip_effect_get_instance_private(clip_effect); cogl_pipeline_set_layer_texture (priv->pipeline, 0, texture); - cogl_pipeline_set_layer_texture(priv->pipeline, 1, priv->corner_texture); return cogl_object_ref (priv->pipeline); } @@ -108,63 +50,6 @@ meta_clip_effect_dispose(GObject *gobject) G_OBJECT_CLASS (meta_clip_effect_parent_class)->dispose (gobject); } -static -CoglTexture *gen_texture(void) -{ - int radius = meta_prefs_get_round_corner_radius(); - int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, radius); - uint8_t *pixel = g_malloc0(stride * radius); - ClutterBackend *backend = clutter_get_default_backend (); - CoglContext *ctx = clutter_backend_get_cogl_context (backend); - cairo_surface_t *image = - cairo_image_surface_create_for_data(pixel, - CAIRO_FORMAT_ARGB32, - radius, - radius, - stride); - cairo_t *cr = cairo_create(image); - - /* draw a 1 / 4 circel, a small texture sized with radius x radius - * texture will be look like this: - * - * XXXX - * XXXXXXX - * XXXXXXXXX - * XXXXXXXXXX - * XXXXXXXXXXX - * XXXXXXXXXXX - * - */ - - cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.0); - cairo_fill(cr); - cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); - cairo_move_to(cr, 0, radius); - cairo_arc(cr, radius, radius, radius, M_PI, 1.5 * M_PI); - cairo_line_to(cr, radius, radius); - cairo_line_to(cr, 0, radius); - cairo_close_path (cr); - cairo_fill(cr); - - cairo_surface_flush(image); - - GError *error = NULL; - CoglTexture2D *texture = - cogl_texture_2d_new_from_data(ctx, radius, radius, - COGL_PIXEL_FORMAT_ARGB_8888, - stride, pixel, &error); - if (error) - { - g_warning ("Failed to allocate mask texture: %s", error->message); - g_error_free (error); - g_clear_pointer(&texture, cogl_object_unref); - } - g_free(pixel); - cairo_destroy(cr); - cairo_surface_destroy (image); - return COGL_TEXTURE(texture); -} - static void meta_clip_effect_class_init(MetaClipEffectClass *klass) { @@ -190,7 +75,6 @@ meta_clip_effect_init(MetaClipEffect *self) clutter_backend_get_cogl_context (clutter_get_default_backend ()); klass->base_pipeline = cogl_pipeline_new (ctx); - klass->base_corner_texture = gen_texture(); snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, ROUNDED_CLIP_FRAGMENT_SHADER_DECLARATIONS, @@ -202,8 +86,6 @@ meta_clip_effect_init(MetaClipEffect *self) } priv->pipeline = cogl_pipeline_copy (klass->base_pipeline); - priv->corner_texture = klass->base_corner_texture; - // g_print("corner ref: %ld\n", COGL_OBJECT(priv->corner_texture)->ref_count); priv->actor = NULL; } @@ -223,65 +105,94 @@ meta_clip_effect_set_bounds(MetaClipEffect *effect, g_return_if_fail(priv->pipeline && priv->actor); float radius = meta_prefs_get_round_corner_radius(); + float border = meta_prefs_get_border_width(); priv->bounds.x = _bounds->x + padding[0]; priv->bounds.y = _bounds->y + padding[2]; priv->bounds.width = _bounds->width - padding[1] - padding[0]; priv->bounds.height = _bounds->height - padding[2] - padding[3]; + + float x1 = priv->bounds.x; + float y1 = priv->bounds.y; + float x2 = priv->bounds.width + x1; + float y2 = priv->bounds.height + y1; float w, h; clutter_actor_get_size(priv->actor, &w, &h); int location_skip = cogl_pipeline_get_uniform_location(priv->pipeline, "skip"); - int location_opacity = - cogl_pipeline_get_uniform_location(priv->pipeline, "opacity"); - int location_offset_lt = - cogl_pipeline_get_uniform_location(priv->pipeline, "offset_lt"); - int location_offset_rt = - cogl_pipeline_get_uniform_location(priv->pipeline, "offset_rt"); - int location_offset_lb = - cogl_pipeline_get_uniform_location(priv->pipeline, "offset_lb"); - int location_offset_rb = - cogl_pipeline_get_uniform_location(priv->pipeline, "offset_rb"); - int location_corner_scale = - cogl_pipeline_get_uniform_location(priv->pipeline, "corner_scale"); int location_bounds = cogl_pipeline_get_uniform_location(priv->pipeline, "bounds"); - - float bounds[] = { - priv->bounds.x / w, - priv->bounds.y / h, - (priv->bounds.x + priv->bounds.width) / w, - (priv->bounds.y + priv->bounds.height) / h + int location_corner_centers_1 = + cogl_pipeline_get_uniform_location(priv->pipeline, "corner_centers_1"); + int location_corner_centers_2 = + cogl_pipeline_get_uniform_location(priv->pipeline, "corner_centers_2"); + int location_inner_bounds = + cogl_pipeline_get_uniform_location(priv->pipeline, "inner_bounds"); + int location_inner_corner_centers_1 = + cogl_pipeline_get_uniform_location(priv->pipeline, "inner_corner_centers_1"); + int location_inner_corner_centers_2 = + cogl_pipeline_get_uniform_location(priv->pipeline, "inner_corner_centers_2"); + int location_pixel_step = + cogl_pipeline_get_uniform_location(priv->pipeline, "pixel_step"); + int location_border_width = + cogl_pipeline_get_uniform_location(priv->pipeline, "border_width"); + + + float bounds[] = { x1, y1, x2, y2 }; + float corner_centers_1[] = { + x1 + radius, + y1 + radius, + x2 - radius, + y1 + radius + }; + float corner_centers_2[] = { + x2 - radius, + y2 - radius, + x1 + radius, + y2 - radius + }; + float inner_bounds[] = { x1 + border, y1 + border, x2 - border, y2 - border }; + + float inner_corner_centers_1[] = { + x1 + radius, + y1 + radius, + x2 - radius, + y1 + radius + }; + float inner_corner_centers_2[] = { + x2 - radius, + y2 - radius, + x1 + radius, + y2 - radius }; - float corner_scale[] = { w / radius , h / radius }; - float top = priv->bounds.y; - float left = priv->bounds.x; - float right = w - priv->bounds.width - priv->bounds.x; - float bottom = h - priv->bounds.height - priv->bounds.y; - float offset_lt[] = { left / (float) radius, top / (float)radius }; - float offset_rt[] = { right / (float) radius, top / (float)radius }; - float offset_lb[] = { left / (float) radius, bottom / (float)radius }; - float offset_rb[] = { right / (float) radius, bottom / (float)radius }; + float pixel_step[] = { 1. / w, 1. / h }; cogl_pipeline_set_uniform_float(priv->pipeline, - location_offset_lt, 2, 1, offset_lt); + location_bounds, + 4, 1, bounds); + cogl_pipeline_set_uniform_float(priv->pipeline, + location_corner_centers_1, + 4, 1, corner_centers_1); cogl_pipeline_set_uniform_float(priv->pipeline, - location_offset_rt, 2, 1, offset_rt); + location_corner_centers_2, + 4, 1, corner_centers_2); cogl_pipeline_set_uniform_float(priv->pipeline, - location_offset_lb, 2, 1, offset_lb); + location_inner_bounds, + 4, 1, inner_bounds); cogl_pipeline_set_uniform_float(priv->pipeline, - location_offset_rb, 2, 1, offset_rb); + location_inner_corner_centers_1, + 4, 1, inner_corner_centers_1); cogl_pipeline_set_uniform_float(priv->pipeline, - location_corner_scale, 2, 1, corner_scale); + location_inner_corner_centers_2, + 4, 1, inner_corner_centers_2); cogl_pipeline_set_uniform_float(priv->pipeline, - location_bounds, 4, 1, bounds); - cogl_pipeline_set_uniform_1f(priv->pipeline, - location_opacity, - clutter_actor_get_opacity(priv->actor) / 255.0); + location_pixel_step, + 2, 1, pixel_step); cogl_pipeline_set_uniform_1i(priv->pipeline, location_skip, 0); + cogl_pipeline_set_uniform_1f(priv->pipeline, location_border_width, border); } void @@ -291,14 +202,9 @@ meta_clip_effect_skip(MetaClipEffect *effect) g_return_if_fail(priv->pipeline && priv->actor); - int location_opacity = - cogl_pipeline_get_uniform_location(priv->pipeline, "opacity"); int location_skip = cogl_pipeline_get_uniform_location(priv->pipeline, "skip"); - cogl_pipeline_set_uniform_1f(priv->pipeline, - location_opacity, - clutter_actor_get_opacity(priv->actor) / 255.0); cogl_pipeline_set_uniform_1i(priv->pipeline, location_skip, 1); } @@ -308,30 +214,4 @@ meta_clip_effect_get_bounds(MetaClipEffect *effect, { MetaClipEffectPrivate *priv = meta_clip_effect_get_instance_private(effect); *bounds = priv->bounds; -} - -void -meta_clip_effect_update_corner_texture(MetaClipEffect *effect) -{ - MetaClipEffectClass *klass = META_CLIP_EFFECT_GET_CLASS(effect); - MetaClipEffectPrivate *priv = meta_clip_effect_get_instance_private(effect); - - if (klass->base_corner_texture == priv->corner_texture) - { - CoglTexture *new_texture = gen_texture(); - if (new_texture != NULL) - { - cogl_object_unref(klass->base_corner_texture); - klass->base_corner_texture = new_texture; - priv->corner_texture = klass->base_corner_texture; - - cogl_pipeline_set_layer_texture(priv->pipeline, 1, priv->corner_texture); - } - } else { - // it's need-not call `cogl_object_unref` to the old texture - priv->corner_texture = klass->base_corner_texture; - // because this function will call `cogl_object_unref` to the old texture - // at the same time, this function will add the reference count of new texture - cogl_pipeline_set_layer_texture(priv->pipeline, 1, priv->corner_texture); - } }
\ No newline at end of file |