[gnome-shell] Lightbox: complete radial effect for modal dialogs



commit fc4bc5277a686cedab7dad248ed33c34ab78011c
Author: Giovanni Campagna <gcampagna src gnome org>
Date:   Thu Mar 6 16:17:36 2014 +0100

    Lightbox: complete radial effect for modal dialogs
    
    Rework the radial effect to use similar code to MetaBackground,
    and adjust parameters to make it more noticeable.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=725830

 js/ui/lightbox.js     |   99 ++++++++++++++++++++++++++++++++++++-------------
 js/ui/overview.js     |   15 ++-----
 src/shell-glsl-quad.c |   49 +++++++++++++++++++-----
 src/shell-glsl-quad.h |    8 ++++
 4 files changed, 124 insertions(+), 47 deletions(-)
---
diff --git a/js/ui/lightbox.js b/js/ui/lightbox.js
index e8d391f..4b07deb 100644
--- a/js/ui/lightbox.js
+++ b/js/ui/lightbox.js
@@ -11,30 +11,60 @@ const Params = imports.misc.params;
 const Tweener = imports.ui.tweener;
 
 const DEFAULT_FADE_FACTOR = 0.4;
+const VIGNETTE_BRIGHTNESS = 0.8;
+const VIGNETTE_SHARPNESS = 0.7;
 
-const GLSL_DIM_EFFECT_DECLARATIONS = '\
-float compute_dim_factor (const vec2 coords) {\
-   vec2 dist = coords - vec2(0.5, 0.5); \
-   float elipse_radius = 0.5; \
-   /* interpolate darkening value, based on distance from screen center */ \
-   float val = min(length(dist), elipse_radius); \
-   return mix(0.3, 1.0, val / elipse_radius) * 0.4; \
-}';
-const GLSL_DIM_EFFECT_CODE = '\
-   float a = compute_dim_factor (cogl_tex_coord0_in.xy);\
-   cogl_color_out = vec4(0, 0, 0, cogl_color_in.a * a);'
-;
+const VIGNETTE_DECLARATIONS = '\
+uniform float brightness;\n\
+uniform float vignette_sharpness;\n';
+
+const VIGNETTE_CODE = '\
+cogl_color_out.a = cogl_color_in.a;\n\
+cogl_color_out.rgb = vec3(0.0, 0.0, 0.0);\n\
+vec2 position = cogl_tex_coord_in[0].xy - 0.5;\n\
+float t = length(2.0 * position);\n\
+t = clamp(t, 0.0, 1.0);\n\
+float pixel_brightness = mix(1.0, 1.0 - vignette_sharpness, t);\n\
+cogl_color_out.a = cogl_color_out.a * (1 - pixel_brightness * brightness);';
 
 const RadialShaderQuad = new Lang.Class({
     Name: 'RadialShaderQuad',
     Extends: Shell.GLSLQuad,
 
+    _init: function(params) {
+        this.parent(params);
+
+        this._brightnessLocation = this.get_uniform_location('brightness');
+        this._sharpnessLocation = this.get_uniform_location('vignette_sharpness');
+
+        this.brightness = 1.0;
+        this.vignetteSharpness = 0.0;
+    },
+
     vfunc_build_pipeline: function() {
         this.add_glsl_snippet(Shell.SnippetHook.FRAGMENT,
-                              GLSL_DIM_EFFECT_DECLARATIONS,
-                              GLSL_DIM_EFFECT_CODE,
-                              true);
+                              VIGNETTE_DECLARATIONS, VIGNETTE_CODE, true);
+    },
+
+    get brightness() {
+        return this._brightness;
+    },
+
+    set brightness(v) {
+        this._brightness = v;
+        this.set_uniform_float(this._brightnessLocation,
+                               1, [this._brightness]);
     },
+
+    get vignetteSharpness() {
+        return this._sharpness;
+    },
+
+    set vignetteSharpness(v) {
+        this._sharpness = v;
+        this.set_uniform_float(this._sharpnessLocation,
+                               1, [this._sharpness]);
+    }
 });
 
 /**
@@ -75,6 +105,7 @@ const Lightbox = new Lang.Class({
         this._container = container;
         this._children = container.get_children();
         this._fadeFactor = params.fadeFactor;
+        this._radialEffect = params.radialEffect;
         if (params.radialEffect)
             this.actor = new RadialShaderQuad({ x: 0,
                                                 y: 0,
@@ -82,6 +113,7 @@ const Lightbox = new Lang.Class({
         else
             this.actor = new St.Bin({ x: 0,
                                       y: 0,
+                                      opacity: 0,
                                       style_class: 'lightbox',
                                       reactive: params.inhibitEvents });
 
@@ -133,11 +165,10 @@ const Lightbox = new Lang.Class({
         fadeInTime = fadeInTime || 0;
 
         Tweener.removeTweens(this.actor);
-        if (fadeInTime != 0) {
-            this.shown = false;
-            this.actor.opacity = 0;
+        if (this._radialEffect) {
             Tweener.addTween(this.actor,
-                             { opacity: 255 * this._fadeFactor,
+                             { brightness: VIGNETTE_BRIGHTNESS,
+                               vignetteSharpness: VIGNETTE_SHARPNESS,
                                time: fadeInTime,
                                transition: 'easeOutQuad',
                                onComplete: Lang.bind(this, function() {
@@ -146,10 +177,17 @@ const Lightbox = new Lang.Class({
                                })
                              });
         } else {
-            this.actor.opacity = 255 * this._fadeFactor;
-            this.shown = true;
-            this.emit('shown');
+            Tweener.addTween(this.actor,
+                             { opacity: 255 * this._fadeFactor,
+                               time: fadeInTime,
+                               transition: 'easeOutQuad',
+                               onComplete: Lang.bind(this, function() {
+                                   this.shown = true;
+                                   this.emit('shown');
+                               })
+                             });
         }
+
         this.actor.show();
     },
 
@@ -158,9 +196,11 @@ const Lightbox = new Lang.Class({
 
         this.shown = false;
         Tweener.removeTweens(this.actor);
-        if (fadeOutTime != 0) {
+        if (this._radialEffect) {
             Tweener.addTween(this.actor,
-                             { opacity: 0,
+                             { brightness: 1.0,
+                               vignetteSharpness: 0.0,
+                               opacity: 0,
                                time: fadeOutTime,
                                transition: 'easeOutQuad',
                                onComplete: Lang.bind(this, function() {
@@ -168,7 +208,14 @@ const Lightbox = new Lang.Class({
                                })
                              });
         } else {
-            this.actor.hide();
+            Tweener.addTween(this.actor,
+                             { opacity: 0,
+                               time: fadeOutTime,
+                               transition: 'easeOutQuad',
+                               onComplete: Lang.bind(this, function() {
+                                   this.actor.hide();
+                               })
+                             });
         }
     },
 
diff --git a/js/ui/overview.js b/js/ui/overview.js
index db52c54..a60a966 100644
--- a/js/ui/overview.js
+++ b/js/ui/overview.js
@@ -14,6 +14,7 @@ const Gdk = imports.gi.Gdk;
 const Background = imports.ui.background;
 const DND = imports.ui.dnd;
 const LayoutManager = imports.ui.layout;
+const Lightbox = imports.ui.lightbox;
 const Main = imports.ui.main;
 const MessageTray = imports.ui.messageTray;
 const OverviewControls = imports.ui.overviewControls;
@@ -196,11 +197,7 @@ const Overview = new Lang.Class({
 
             Tweener.addTween(background,
                              { brightness: 1.0,
-                               time: SHADE_ANIMATION_TIME,
-                               transition: 'easeOutQuad'
-                             });
-            Tweener.addTween(background,
-                             { vignetteSharpness: 0.0,
+                               vignetteSharpness: 0.0,
                                time: SHADE_ANIMATION_TIME,
                                transition: 'easeOutQuad'
                              });
@@ -213,12 +210,8 @@ const Overview = new Lang.Class({
             let background = backgrounds[i]._delegate;
 
             Tweener.addTween(background,
-                             { brightness: 0.8,
-                               time: SHADE_ANIMATION_TIME,
-                               transition: 'easeOutQuad'
-                             });
-            Tweener.addTween(background,
-                             { vignetteSharpness: 0.7,
+                             { brightness: Lightbox.VIGNETTE_BRIGHTNESS,
+                               vignetteSharpness: Lightbox.VIGNETTE_SHARPNESS,
                                time: SHADE_ANIMATION_TIME,
                                transition: 'easeOutQuad'
                              });
diff --git a/src/shell-glsl-quad.c b/src/shell-glsl-quad.c
index 5e3ce18..22edc92 100644
--- a/src/shell-glsl-quad.c
+++ b/src/shell-glsl-quad.c
@@ -24,7 +24,6 @@ G_DEFINE_TYPE (ShellGLSLQuad, shell_glsl_quad, CLUTTER_TYPE_ACTOR);
 struct _ShellGLSLQuadPrivate
 {
   CoglPipeline  *pipeline;
-  CoglTexture2D *texture;
 };
 
 static void
@@ -40,9 +39,10 @@ shell_glsl_quad_paint (ClutterActor *actor)
   paint_opacity = clutter_actor_get_paint_opacity (actor);
   clutter_actor_get_allocation_box (actor, &box);
 
-  /* semi-transparent black */
   cogl_pipeline_set_color4ub (priv->pipeline,
-                              0, 0, 0,
+                              paint_opacity,
+                              paint_opacity,
+                              paint_opacity,
                               paint_opacity);
   cogl_framebuffer_draw_rectangle (cogl_get_draw_framebuffer (),
                                    priv->pipeline,
@@ -105,7 +105,6 @@ shell_glsl_quad_dispose (GObject *gobject)
   priv = self->priv;
 
   g_clear_pointer (&priv->pipeline, cogl_object_unref);
-  g_clear_pointer (&priv->texture, cogl_object_unref);
 
   G_OBJECT_CLASS (shell_glsl_quad_parent_class)->dispose (gobject);
 }
@@ -123,7 +122,6 @@ shell_glsl_quad_constructed (GObject *object)
   ShellGLSLQuadClass *klass;
   CoglContext *ctx =
     clutter_backend_get_cogl_context (clutter_get_default_backend ());
-  static const uint8_t tex_data[] = { 0, 0, 0, 0 };
 
   G_OBJECT_CLASS (shell_glsl_quad_parent_class)->constructed (object);
 
@@ -144,11 +142,7 @@ shell_glsl_quad_constructed (GObject *object)
 
   self->priv->pipeline = cogl_pipeline_copy (klass->base_pipeline);
 
-  self->priv->texture = cogl_texture_2d_new_from_data (ctx, 1, 1,
-                                                       COGL_PIXEL_FORMAT_RGBA_8888,
-                                                       0, tex_data, NULL);
-  cogl_pipeline_set_layer_texture (self->priv->pipeline, 0,
-                                   COGL_TEXTURE (self->priv->texture));
+  cogl_pipeline_set_layer_null_texture (self->priv->pipeline, 0, COGL_TEXTURE_TYPE_2D);
 }
 
 static void
@@ -164,3 +158,38 @@ shell_glsl_quad_class_init (ShellGLSLQuadClass *klass)
 
   g_type_class_add_private (klass, sizeof (ShellGLSLQuadPrivate));
 }
+
+/**
+ * shell_glsl_quad_get_uniform_location:
+ * @quad: a #ShellGLSLQuad
+ * @name: the uniform name
+ *
+ * Returns: the location of the uniform named @name, that can be
+ *          passed to shell_glsl_quad_set_uniform_float().
+ */
+int
+shell_glsl_quad_get_uniform_location (ShellGLSLQuad *quad,
+                                      const char    *name)
+{
+  return cogl_pipeline_get_uniform_location (quad->priv->pipeline, name);
+}
+
+/**
+ * shell_glsl_quad_set_uniform_float:
+ * @quad: a #ShellGLSLQuad
+ * @uniform: the uniform location (as returned by shell_glsl_quad_get_uniform_location())
+ * @n_components: the number of components in the uniform (eg. 3 for a vec3)
+ * @total_count: the total number of floats in @value
+ * @value: (array length=total_count): the array of floats to set @uniform
+ */
+void
+shell_glsl_quad_set_uniform_float (ShellGLSLQuad *quad,
+                                   int            uniform,
+                                   int            n_components,
+                                   int            total_count,
+                                   const float   *value)
+{
+  cogl_pipeline_set_uniform_float (quad->priv->pipeline, uniform,
+                                   n_components, total_count / n_components,
+                                   value);
+}
diff --git a/src/shell-glsl-quad.h b/src/shell-glsl-quad.h
index 04a9362..f2b19bc 100644
--- a/src/shell-glsl-quad.h
+++ b/src/shell-glsl-quad.h
@@ -61,4 +61,12 @@ void shell_glsl_quad_add_glsl_snippet (ShellGLSLQuad    *quad,
                                        const char       *code,
                                        gboolean          is_replace);
 
+int  shell_glsl_quad_get_uniform_location (ShellGLSLQuad *quad,
+                                           const char    *name);
+void shell_glsl_quad_set_uniform_float    (ShellGLSLQuad *quad,
+                                           int            uniform,
+                                           int            n_components,
+                                           int            total_count,
+                                           const float   *value);
+
 #endif /* __SHELL_GLSL_QUAD_H__ */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]