[gnome-shell] shell: Actually make GLSLEffect an effect
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell] shell: Actually make GLSLEffect an effect
- Date: Mon, 29 Jul 2019 15:57:20 +0000 (UTC)
commit 007d3057364e2d50cba9ece6a6d9da7aeedf5d87
Author: Florian Müllner <fmuellner gnome org>
Date: Fri Jul 26 22:08:52 2019 +0200
shell: Actually make GLSLEffect an effect
A generic, introspectable Shader effect is not only more flexible
than a shader actor, it will also make it much easier to turn
Lightbox into an actor subclass and replace Tweener with Clutter's
own animation support.
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/651
js/ui/lightbox.js | 17 ++++++-----
src/shell-glsl-effect.c | 81 +++++++++++++++++++++++++++++++++++--------------
src/shell-glsl-effect.h | 4 +--
3 files changed, 70 insertions(+), 32 deletions(-)
---
diff --git a/js/ui/lightbox.js b/js/ui/lightbox.js
index 423564097..18a309997 100644
--- a/js/ui/lightbox.js
+++ b/js/ui/lightbox.js
@@ -24,8 +24,8 @@ 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);';
-var RadialShaderQuad = GObject.registerClass(
-class RadialShaderQuad extends Shell.GLSLEffect {
+var RadialShaderEffect = GObject.registerClass(
+class RadialShaderEffect extends Shell.GLSLEffect {
_init(params) {
super._init(params);
@@ -99,12 +99,13 @@ var Lightbox = class Lightbox {
this._children = container.get_children();
this._fadeFactor = params.fadeFactor;
this._radialEffect = Clutter.feature_available(Clutter.FeatureFlags.SHADERS_GLSL) &&
params.radialEffect;
+
+ this.actor = new St.Bin({ reactive: params.inhibitEvents });
+
if (this._radialEffect)
- this.actor = new RadialShaderQuad({ reactive: params.inhibitEvents });
+ this.actor.add_effect(new RadialShaderEffect({ name: 'radial' }));
else
- this.actor = new St.Bin({ opacity: 0,
- style_class: 'lightbox',
- reactive: params.inhibitEvents });
+ this.actor.set({ opacity: 0, style_class: 'lightbox' });
container.add_actor(this.actor);
this.actor.raise_top();
@@ -155,7 +156,7 @@ var Lightbox = class Lightbox {
Tweener.removeTweens(this.actor);
if (this._radialEffect) {
- Tweener.addTween(this.actor,
+ Tweener.addTween(this.actor.get_effect('radial'),
{ brightness: VIGNETTE_BRIGHTNESS,
vignetteSharpness: VIGNETTE_SHARPNESS,
time: fadeInTime,
@@ -186,7 +187,7 @@ var Lightbox = class Lightbox {
this.shown = false;
Tweener.removeTweens(this.actor);
if (this._radialEffect) {
- Tweener.addTween(this.actor,
+ Tweener.addTween(this.actor.get_effect('radial'),
{ brightness: 1.0,
vignetteSharpness: 0.0,
opacity: 0,
diff --git a/src/shell-glsl-effect.c b/src/shell-glsl-effect.c
index 04d39ca51..1ffe9d0d9 100644
--- a/src/shell-glsl-effect.c
+++ b/src/shell-glsl-effect.c
@@ -2,13 +2,11 @@
/**
* SECTION:shell-glsl-effect
- * @short_description: Draw a rectangle using GLSL
+ * @short_description: An offscreen effect using GLSL
*
- * A #ShellGLSLEffect draws one single rectangle, sized to the allocation
- * box, but allows running custom GLSL to the vertex and fragment
- * stages of the graphic pipeline.
- *
- * To ease writing the shader, a single texture layer is also used.
+ * A #ShellGLSLEffect is a #ClutterOffscreenEffect that allows
+ * running custom GLSL to the vertex and fragment stages of the
+ * graphic pipeline.
*/
#include "config.h"
@@ -20,29 +18,65 @@ typedef struct _ShellGLSLEffectPrivate ShellGLSLEffectPrivate;
struct _ShellGLSLEffectPrivate
{
CoglPipeline *pipeline;
+
+ gint tex_width;
+ gint tex_height;
};
-G_DEFINE_TYPE_WITH_PRIVATE (ShellGLSLEffect, shell_glsl_effect, CLUTTER_TYPE_ACTOR);
+G_DEFINE_TYPE_WITH_PRIVATE (ShellGLSLEffect, shell_glsl_effect, CLUTTER_TYPE_OFFSCREEN_EFFECT);
static gboolean
-shell_glsl_effect_get_paint_volume (ClutterActor *actor,
- ClutterPaintVolume *volume)
+shell_glsl_effect_pre_paint (ClutterEffect *effect)
{
- return clutter_paint_volume_set_from_allocation (volume, actor);
+ ShellGLSLEffect *self = SHELL_GLSL_EFFECT (effect);
+ ClutterOffscreenEffect *offscreen_effect = CLUTTER_OFFSCREEN_EFFECT (effect);
+ ShellGLSLEffectPrivate *priv = shell_glsl_effect_get_instance_private (self);
+ ClutterEffectClass *parent_class;
+ CoglHandle texture;
+ gboolean success;
+
+ 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_glsl_effect_parent_class);
+ success = parent_class->pre_paint (effect);
+
+ if (!success)
+ return FALSE;
+
+ texture = clutter_offscreen_effect_get_texture (offscreen_effect);
+ priv->tex_width = cogl_texture_get_width (texture);
+ priv->tex_height = cogl_texture_get_height (texture);
+
+ cogl_pipeline_set_layer_texture (priv->pipeline, 0, texture);
+
+ return TRUE;
}
static void
-shell_glsl_effect_paint (ClutterActor *actor)
+shell_glsl_effect_paint_target (ClutterOffscreenEffect *effect)
{
- ShellGLSLEffect *self = SHELL_GLSL_EFFECT (actor);
+ ShellGLSLEffect *self = SHELL_GLSL_EFFECT (effect);
ShellGLSLEffectPrivate *priv;
+ ClutterActor *actor;
guint8 paint_opacity;
- ClutterActorBox box;
priv = shell_glsl_effect_get_instance_private (self);
+ actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
paint_opacity = clutter_actor_get_paint_opacity (actor);
- clutter_actor_get_allocation_box (actor, &box);
cogl_pipeline_set_color4ub (priv->pipeline,
paint_opacity,
@@ -51,8 +85,8 @@ shell_glsl_effect_paint (ClutterActor *actor)
paint_opacity);
cogl_framebuffer_draw_rectangle (cogl_get_draw_framebuffer (),
priv->pipeline,
- box.x1, box.y1,
- box.x2, box.y2);
+ 0, 0,
+ priv->tex_width, priv->tex_height);
}
@@ -64,7 +98,7 @@ shell_glsl_effect_paint (ClutterActor *actor)
* @code: GLSL code
* @is_replace: wheter Cogl code should be replaced by the custom shader
*
- * Adds a GLSL snippet to the pipeline used for drawing the actor texture.
+ * Adds a GLSL snippet to the pipeline used for drawing the effect texture.
* See #CoglSnippet for details.
*
* This is only valid inside the a call to the build_pipeline() virtual
@@ -149,20 +183,23 @@ shell_glsl_effect_constructed (GObject *object)
priv->pipeline = cogl_pipeline_copy (klass->base_pipeline);
- cogl_pipeline_set_layer_null_texture (priv->pipeline, 0);
+ cogl_pipeline_set_layer_null_texture (klass->base_pipeline, 0);
}
static void
shell_glsl_effect_class_init (ShellGLSLEffectClass *klass)
{
- ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (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_glsl_effect_paint_target;
+
+ effect_class->pre_paint = shell_glsl_effect_pre_paint;
gobject_class->constructed = shell_glsl_effect_constructed;
gobject_class->dispose = shell_glsl_effect_dispose;
-
- actor_class->get_paint_volume = shell_glsl_effect_get_paint_volume;
- actor_class->paint = shell_glsl_effect_paint;
}
/**
diff --git a/src/shell-glsl-effect.h b/src/shell-glsl-effect.h
index 4c1ad7bf2..d943cefb8 100644
--- a/src/shell-glsl-effect.h
+++ b/src/shell-glsl-effect.h
@@ -28,11 +28,11 @@ typedef enum {
#define SHELL_TYPE_GLSL_EFFECT (shell_glsl_effect_get_type ())
G_DECLARE_DERIVABLE_TYPE (ShellGLSLEffect, shell_glsl_effect,
- SHELL, GLSL_EFFECT, ClutterActor)
+ SHELL, GLSL_EFFECT, ClutterOffscreenEffect)
struct _ShellGLSLEffectClass
{
- ClutterActorClass parent_class;
+ ClutterOffscreenEffectClass parent_class;
CoglPipeline *base_pipeline;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]