summarylogtreecommitdiffstats
path: root/meta_clip_effect.c
diff options
context:
space:
mode:
authorLuoYi2021-10-09 19:44:59 +0800
committerLuoYi2021-10-09 19:44:59 +0800
commit6828d3b1e8cb0b41e296c173e37030448c306ac4 (patch)
tree5400e37c5b6551a1e39e7de500a9b2efb9ff5058 /meta_clip_effect.c
parentcf46f104d8acbe30108fb179b12f0e3c1e6c6440 (diff)
downloadaur-6828d3b1e8cb0b41e296c173e37030448c306ac4.tar.gz
try to integrate shell-blur-effect
Diffstat (limited to 'meta_clip_effect.c')
-rw-r--r--meta_clip_effect.c252
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