[gnome-shell/T27795: 61/138] Add new Endless-specific class ShellGridDesaturateEffect
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell/T27795: 61/138] Add new Endless-specific class ShellGridDesaturateEffect
- Date: Tue, 1 Oct 2019 23:34:27 +0000 (UTC)
commit 454312fa16b11449f7ceb335e1caea21fe0782d9
Author: Mario Sanchez Prada <mario endlessm com>
Date: Tue May 9 15:57:30 2017 +0100
Add new Endless-specific class ShellGridDesaturateEffect
This will be used when opening a folder in the desktop, in order
to desaturate all the icons but the one for the folder being opened.
src/meson.build | 2 +
src/shell-grid-desaturate-effect.c | 469 +++++++++++++++++++++++++++++++++++++
src/shell-grid-desaturate-effect.h | 49 ++++
3 files changed, 520 insertions(+)
---
diff --git a/src/meson.build b/src/meson.build
index 56c26dc845..0883d2e44b 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -100,6 +100,7 @@ libshell_public_headers = [
'shell-glsl-effect.h',
'shell-gtk-embed.h',
'shell-global.h',
+ 'shell-grid-desaturate-effect.h',
'shell-invert-lightness-effect.h',
'shell-action-modes.h',
'shell-mount-operation.h',
@@ -133,6 +134,7 @@ libshell_sources = [
'shell-embedded-window.c',
'shell-embedded-window-private.h',
'shell-global.c',
+ 'shell-grid-desaturate-effect.c',
'shell-glsl-effect.c',
'shell-gtk-embed.c',
'shell-invert-lightness-effect.c',
diff --git a/src/shell-grid-desaturate-effect.c b/src/shell-grid-desaturate-effect.c
new file mode 100644
index 0000000000..834cb5a103
--- /dev/null
+++ b/src/shell-grid-desaturate-effect.c
@@ -0,0 +1,469 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Copyright (C) 2010 Intel Corporation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ * Emmanuele Bassi <ebassi linux intel com>
+ */
+
+/**
+ * SECTION:clutter-desaturate-effect
+ * @short_description: A desaturation effect
+ * @see_also: #ClutterEffect, #ClutterOffscreenEffect
+ *
+ * #ShellGridDesaturateEffect is a sub-class of #ClutterEffect that
+ * desaturates the color of an actor and its contents. The strenght
+ * of the desaturation effect is controllable and animatable through
+ * the #ShellGridDesaturateEffect:factor property.
+ *
+ * #ShellGridDesaturateEffect is available since Clutter 1.4
+ */
+
+#include <math.h>
+
+#include "shell-grid-desaturate-effect.h"
+
+#include <cogl/cogl.h>
+
+static CoglPipeline *base_pipeline = NULL;
+
+struct _ShellGridDesaturateEffect
+{
+ ClutterOffscreenEffect parent_instance;
+
+ /* the desaturation factor, also known as "strength" */
+ gdouble factor;
+
+ /* an area not to be shaded */
+ ClutterRect *unshaded_rect;
+
+ gint factor_uniform;
+ gint unshaded_uniform;
+
+ gint tex_width;
+ gint tex_height;
+
+ gboolean unshaded_uniform_dirty;
+
+ CoglPipeline *pipeline;
+};
+
+/* the magic gray vec3 has been taken from the NTSC conversion weights
+ * as defined by:
+ *
+ * "OpenGL Superbible, 4th edition"
+ * -- Richard S. Wright Jr, Benjamin Lipchak, Nicholas Haemel
+ * Addison-Wesley
+ */
+static const gchar *desaturate_glsl_declarations =
+ "uniform float factor;\n"
+ "uniform vec4 unshaded;\n"
+ "\n"
+ "vec3 desaturate (const vec3 color, const float desaturation)\n"
+ "{\n"
+ " if ((cogl_tex_coord0_in[0] > unshaded[0]) && (cogl_tex_coord0_in[0] < unshaded[2]) &&\n"
+ " (cogl_tex_coord0_in[1] > unshaded[1]) && (cogl_tex_coord0_in[1] < unshaded[3]))\n"
+ " return color;\n"
+ " const vec3 gray_conv = vec3 (0.299, 0.587, 0.114);\n"
+ " vec3 gray = vec3 (dot (gray_conv, color));\n"
+ " return vec3 (mix (color.rgb, gray, desaturation));\n"
+ "}\n";
+
+static const gchar *desaturate_glsl_source =
+ " cogl_color_out.rgb = desaturate (cogl_color_out.rgb, factor);\n";
+
+enum
+{
+ PROP_0,
+
+ PROP_FACTOR,
+ PROP_UNSHADED_RECT,
+
+ PROP_LAST
+};
+
+static GParamSpec *obj_props[PROP_LAST];
+
+G_DEFINE_TYPE (ShellGridDesaturateEffect,
+ shell_grid_desaturate_effect,
+ CLUTTER_TYPE_OFFSCREEN_EFFECT);
+
+static void update_unshaded_uniform (ShellGridDesaturateEffect *self);
+
+static gboolean
+shell_grid_desaturate_effect_pre_paint (ClutterEffect *effect)
+{
+ ShellGridDesaturateEffect *self = SHELL_GRID_DESATURATE_EFFECT (effect);
+ ClutterEffectClass *parent_class;
+
+ if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)))
+ return FALSE;
+
+ if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
+ {
+ /* if we don't have support for GLSL shaders then we
+ * forcibly disable the ActorMeta
+ */
+ g_warning ("Unable to use the ShaderEffect: the graphics hardware "
+ "or the current GL driver does not implement support "
+ "for the GLSL shading language.");
+ clutter_actor_meta_set_enabled (CLUTTER_ACTOR_META (effect), FALSE);
+ return FALSE;
+ }
+
+ parent_class = CLUTTER_EFFECT_CLASS (shell_grid_desaturate_effect_parent_class);
+ if (parent_class->pre_paint (effect))
+ {
+ ClutterOffscreenEffect *offscreen_effect =
+ CLUTTER_OFFSCREEN_EFFECT (effect);
+ CoglHandle texture;
+
+ texture = clutter_offscreen_effect_get_texture (offscreen_effect);
+ self->tex_width = cogl_texture_get_width (texture);
+ self->tex_height = cogl_texture_get_height (texture);
+
+ if (self->unshaded_uniform_dirty)
+ update_unshaded_uniform (self);
+
+ cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
+
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+static void
+shell_grid_desaturate_effect_paint_target (ClutterOffscreenEffect *effect)
+{
+ ShellGridDesaturateEffect *self = SHELL_GRID_DESATURATE_EFFECT (effect);
+ ClutterActor *actor;
+ CoglHandle texture;
+ guint8 paint_opacity;
+
+ texture = clutter_offscreen_effect_get_texture (effect);
+ cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
+
+ actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
+ paint_opacity = clutter_actor_get_paint_opacity (actor);
+
+ cogl_pipeline_set_color4ub (self->pipeline,
+ paint_opacity,
+ paint_opacity,
+ paint_opacity,
+ paint_opacity);
+
+ cogl_framebuffer_draw_rectangle (cogl_get_draw_framebuffer (),
+ self->pipeline,
+ 0, 0,
+ cogl_texture_get_width (texture),
+ cogl_texture_get_height (texture));
+}
+
+static void
+shell_grid_desaturate_effect_dispose (GObject *gobject)
+{
+ ShellGridDesaturateEffect *self = SHELL_GRID_DESATURATE_EFFECT (gobject);
+
+ if (self->pipeline != NULL)
+ {
+ cogl_object_unref (self->pipeline);
+ self->pipeline = NULL;
+ }
+
+ clutter_rect_free (self->unshaded_rect);
+ self->unshaded_rect = NULL;
+
+ G_OBJECT_CLASS (shell_grid_desaturate_effect_parent_class)->dispose (gobject);
+}
+
+static void
+shell_grid_desaturate_effect_set_property (GObject *gobject,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ ShellGridDesaturateEffect *effect = SHELL_GRID_DESATURATE_EFFECT (gobject);
+
+ switch (prop_id)
+ {
+ case PROP_FACTOR:
+ shell_grid_desaturate_effect_set_factor (effect,
+ g_value_get_double (value));
+ break;
+
+ case PROP_UNSHADED_RECT:
+ shell_grid_desaturate_effect_set_unshaded_rect (effect,
+ g_value_get_boxed (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+shell_grid_desaturate_effect_get_property (GObject *gobject,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ ShellGridDesaturateEffect *effect = SHELL_GRID_DESATURATE_EFFECT (gobject);
+
+ switch (prop_id)
+ {
+ case PROP_FACTOR:
+ g_value_set_double (value, effect->factor);
+ break;
+
+ case PROP_UNSHADED_RECT:
+ g_value_set_boxed (value, effect->unshaded_rect);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+update_factor_uniform (ShellGridDesaturateEffect *self)
+{
+ if (self->factor_uniform > -1)
+ cogl_pipeline_set_uniform_1f (self->pipeline,
+ self->factor_uniform,
+ self->factor);
+}
+
+static void
+update_unshaded_uniform (ShellGridDesaturateEffect *self)
+{
+ float values[4] = { 0., 0., 0., 0.};
+ ClutterOffscreenEffect *offscreen_effect = CLUTTER_OFFSCREEN_EFFECT (self);
+ CoglHandle texture;
+ float width, height;
+
+ if (self->unshaded_uniform == -1)
+ return;
+
+ texture = clutter_offscreen_effect_get_texture (offscreen_effect);
+ if (texture == COGL_INVALID_HANDLE)
+ goto out;
+
+ width = cogl_texture_get_width (texture);
+ height = cogl_texture_get_height (texture);
+
+ values[0] = MIN (1.0, self->unshaded_rect->origin.x / width);
+ values[1] = MIN (1.0, self->unshaded_rect->origin.y / height);
+ values[2] = MIN (1.0, (self->unshaded_rect->origin.x + self->unshaded_rect->size.width) / width);
+ values[3] = MIN (1.0, (self->unshaded_rect->origin.y + self->unshaded_rect->size.height) / height);
+
+ self->unshaded_uniform_dirty = FALSE;
+
+ out:
+ cogl_pipeline_set_uniform_float (self->pipeline,
+ self->unshaded_uniform,
+ 4, 1,
+ values);
+}
+
+static void
+shell_grid_desaturate_effect_class_init (ShellGridDesaturateEffectClass *klass)
+{
+ ClutterEffectClass *effect_class = CLUTTER_EFFECT_CLASS (klass);
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ ClutterOffscreenEffectClass *offscreen_class;
+
+ offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
+ offscreen_class->paint_target = shell_grid_desaturate_effect_paint_target;
+
+ effect_class->pre_paint = shell_grid_desaturate_effect_pre_paint;
+
+ /**
+ * ShellGridDesaturateEffect:factor:
+ *
+ * The desaturation factor, between 0.0 (no desaturation) and 1.0 (full
+ * desaturation).
+ */
+ obj_props[PROP_FACTOR] =
+ g_param_spec_double ("factor",
+ "Factor",
+ "The desaturation factor",
+ 0.0, 1.0,
+ 1.0,
+ G_PARAM_READWRITE);
+
+ /**
+ * ShellGridDesaturateEffect:unshaded-rect:
+ *
+ * The unshaded rectangle.
+ */
+ obj_props[PROP_UNSHADED_RECT] =
+ g_param_spec_boxed ("unshaded-rect",
+ "Unshaded rect",
+ "The unshaded rectangle",
+ CLUTTER_TYPE_RECT,
+ G_PARAM_READWRITE);
+
+ gobject_class->dispose = shell_grid_desaturate_effect_dispose;
+ gobject_class->set_property = shell_grid_desaturate_effect_set_property;
+ gobject_class->get_property = shell_grid_desaturate_effect_get_property;
+
+ g_object_class_install_properties (gobject_class, PROP_LAST, obj_props);
+}
+
+static void
+shell_grid_desaturate_effect_init (ShellGridDesaturateEffect *self)
+{
+ if (G_UNLIKELY (base_pipeline == NULL))
+ {
+ CoglContext *ctx =
+ clutter_backend_get_cogl_context (clutter_get_default_backend ());
+ CoglSnippet *snippet;
+
+ base_pipeline = cogl_pipeline_new (ctx);
+
+ snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
+ desaturate_glsl_declarations,
+ desaturate_glsl_source);
+ cogl_pipeline_add_snippet (base_pipeline, snippet);
+ cogl_object_unref (snippet);
+
+ cogl_pipeline_set_layer_null_texture (base_pipeline, 0);
+ }
+
+ self->pipeline = cogl_pipeline_copy (base_pipeline);
+
+ self->factor_uniform =
+ cogl_pipeline_get_uniform_location (self->pipeline, "factor");
+
+ self->factor = 1.0;
+
+ update_factor_uniform (self);
+
+ self->unshaded_rect = (ClutterRect *) clutter_rect_zero ();
+
+ self->unshaded_uniform =
+ cogl_pipeline_get_uniform_location (self->pipeline, "unshaded");
+
+ update_unshaded_uniform (self);
+}
+
+/**
+ * shell_grid_desaturate_effect_new:
+ * @factor: the desaturation factor, between 0.0 and 1.0
+ *
+ * Creates a new #ShellGridDesaturateEffect to be used with
+ * clutter_actor_add_effect()
+ *
+ * Return value: the newly created #ShellGridDesaturateEffect or %NULL
+ */
+ClutterEffect *
+shell_grid_desaturate_effect_new (gdouble factor)
+{
+ g_return_val_if_fail (factor >= 0.0 && factor <= 1.0, NULL);
+
+ return g_object_new (CLUTTER_TYPE_DESATURATE_EFFECT,
+ "factor", factor,
+ NULL);
+}
+
+/**
+ * shell_grid_desaturate_effect_set_factor:
+ * @effect: a #ShellGridDesaturateEffect
+ * @factor: the desaturation factor, between 0.0 and 1.0
+ *
+ * Sets the desaturation factor for @effect, with 0.0 being "do not desaturate"
+ * and 1.0 being "fully desaturate"
+ */
+void
+shell_grid_desaturate_effect_set_factor (ShellGridDesaturateEffect *effect,
+ gdouble factor)
+{
+ g_return_if_fail (SHELL_IS_GRID_DESATURATE_EFFECT (effect));
+ g_return_if_fail (factor >= 0.0 && factor <= 1.0);
+
+ if (fabsf (effect->factor - factor) >= 0.00001)
+ {
+ effect->factor = factor;
+ update_factor_uniform (effect);
+
+ clutter_effect_queue_repaint (CLUTTER_EFFECT (effect));
+
+ g_object_notify_by_pspec (G_OBJECT (effect), obj_props[PROP_FACTOR]);
+ }
+}
+
+/**
+ * shell_grid_desaturate_effect_get_unshaded_rect:
+ * @effect: a #ShellGridDesaturateEffect
+ *
+ * Retrieves the unshaded area of @effect
+ *
+ * Return value: (transfer none): the unshaded area
+ */
+ClutterRect *
+shell_grid_desaturate_effect_get_unshaded_rect (ShellGridDesaturateEffect *effect)
+{
+ g_return_val_if_fail (SHELL_IS_GRID_DESATURATE_EFFECT (effect), NULL);
+
+ return effect->unshaded_rect;
+}
+
+/**
+ * shell_grid_desaturate_effect_set_unshaded_rect:
+ * @effect: a #ShellGridDesaturateEffect
+ * @rect: (allow-none): the unshaded area
+ *
+ * Sets an unshaded area to the effect
+ */
+void
+shell_grid_desaturate_effect_set_unshaded_rect (ShellGridDesaturateEffect *effect,
+ ClutterRect *rect)
+{
+ g_return_if_fail (SHELL_IS_GRID_DESATURATE_EFFECT (effect));
+
+ if (!clutter_rect_equals (rect, effect->unshaded_rect))
+ {
+ clutter_rect_free (effect->unshaded_rect);
+ effect->unshaded_rect = clutter_rect_copy (rect);
+ effect->unshaded_uniform_dirty = TRUE;
+
+ clutter_effect_queue_repaint (CLUTTER_EFFECT (effect));
+
+ g_object_notify_by_pspec (G_OBJECT (effect), obj_props[PROP_UNSHADED_RECT]);
+ }
+}
+
+/**
+ * shell_grid_desaturate_effect_get_factor:
+ * @effect: a #ShellGridDesaturateEffect
+ *
+ * Retrieves the desaturation factor of @effect
+ *
+ * Return value: the desaturation factor
+ */
+gdouble
+shell_grid_desaturate_effect_get_factor (ShellGridDesaturateEffect *effect)
+{
+ g_return_val_if_fail (SHELL_IS_GRID_DESATURATE_EFFECT (effect), 0.0);
+
+ return effect->factor;
+}
diff --git a/src/shell-grid-desaturate-effect.h b/src/shell-grid-desaturate-effect.h
new file mode 100644
index 0000000000..17bc7cec3e
--- /dev/null
+++ b/src/shell-grid-desaturate-effect.h
@@ -0,0 +1,49 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Copyright (C) 2010 Intel Corporation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ * Emmanuele Bassi <ebassi linux intel com>
+ */
+
+#ifndef __SHELL_GRID_DESATURATE_EFFECT_H__
+#define __SHELL_GRID_DESATURATE_EFFECT_H__
+
+#include <clutter/clutter.h>
+
+G_BEGIN_DECLS
+
+#define SHELL_TYPE_GRID_DESATURATE_EFFECT (shell_grid_desaturate_effect_get_type ())
+G_DECLARE_FINAL_TYPE (ShellGridDesaturateEffect, shell_grid_desaturate_effect,
+ SHELL, GRID_DESATURATE_EFFECT, ClutterOffscreenEffect)
+
+ClutterEffect *shell_grid_desaturate_effect_new (gdouble factor);
+
+void shell_grid_desaturate_effect_set_factor (ShellGridDesaturateEffect *effect,
+ gdouble factor);
+gdouble shell_grid_desaturate_effect_get_factor (ShellGridDesaturateEffect *effect);
+
+void shell_grid_desaturate_effect_set_unshaded_rect (ShellGridDesaturateEffect *effect,
+ ClutterRect *rect);
+
+ClutterRect * shell_grid_desaturate_effect_get_unshaded_rect (ShellGridDesaturateEffect *effect);
+
+G_END_DECLS
+
+#endif /* __SHELL_GRID_DESATURATE_EFFECT_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]