screenShield: Blur background
This is a moderately fast two-pass gaussian blur implementation. It downscales the framebuffer by half before applying the gaussian shader, which cuts down rendering time quite considerably. The blur shader takes 3 uniforms as input: the blur radius; whether to blur vertically or horizontally; and a brightness value. The blur radius is treated as an integer in C land to simplify calculations. The vertical parameter is treated as an integer by the shader simply due to Cogl not having proper boolean support in snippets. At last, brightness is also added to avoid needing to use an extra effect to achieve that.
This commit is contained in:
parent
10a194e6ed
commit
caf0c8dd7d
@ -16,6 +16,7 @@ const Overview = imports.ui.overview;
|
|||||||
const MessageTray = imports.ui.messageTray;
|
const MessageTray = imports.ui.messageTray;
|
||||||
const ShellDBus = imports.ui.shellDBus;
|
const ShellDBus = imports.ui.shellDBus;
|
||||||
const SmartcardManager = imports.misc.smartcardManager;
|
const SmartcardManager = imports.misc.smartcardManager;
|
||||||
|
const Params = imports.misc.params;
|
||||||
|
|
||||||
const SCREENSAVER_SCHEMA = 'org.gnome.desktop.screensaver';
|
const SCREENSAVER_SCHEMA = 'org.gnome.desktop.screensaver';
|
||||||
const LOCK_ENABLED_KEY = 'lock-enabled';
|
const LOCK_ENABLED_KEY = 'lock-enabled';
|
||||||
@ -25,6 +26,10 @@ const LOCKDOWN_SCHEMA = 'org.gnome.desktop.lockdown';
|
|||||||
const DISABLE_LOCK_KEY = 'disable-lock-screen';
|
const DISABLE_LOCK_KEY = 'disable-lock-screen';
|
||||||
|
|
||||||
const LOCKED_STATE_STR = 'screenShield.locked';
|
const LOCKED_STATE_STR = 'screenShield.locked';
|
||||||
|
|
||||||
|
const BLUR_BRIGHTNESS = 0.55;
|
||||||
|
const BLUR_RADIUS = 70;
|
||||||
|
|
||||||
// fraction of screen height the arrow must reach before completing
|
// fraction of screen height the arrow must reach before completing
|
||||||
// the slide up automatically
|
// the slide up automatically
|
||||||
var ARROW_DRAG_THRESHOLD = 0.1;
|
var ARROW_DRAG_THRESHOLD = 0.1;
|
||||||
@ -584,6 +589,7 @@ var ScreenShield = class {
|
|||||||
_createBackground(monitorIndex) {
|
_createBackground(monitorIndex) {
|
||||||
let monitor = Main.layoutManager.monitors[monitorIndex];
|
let monitor = Main.layoutManager.monitors[monitorIndex];
|
||||||
let widget = new St.Widget({ style_class: 'screen-shield-background',
|
let widget = new St.Widget({ style_class: 'screen-shield-background',
|
||||||
|
clip_to_allocation: true,
|
||||||
x: monitor.x,
|
x: monitor.x,
|
||||||
y: monitor.y,
|
y: monitor.y,
|
||||||
width: monitor.width,
|
width: monitor.width,
|
||||||
@ -597,6 +603,15 @@ var ScreenShield = class {
|
|||||||
this._bgManagers.push(bgManager);
|
this._bgManagers.push(bgManager);
|
||||||
|
|
||||||
this._backgroundGroup.add_child(widget);
|
this._backgroundGroup.add_child(widget);
|
||||||
|
|
||||||
|
widget.add_effect(new Shell.BlurEffect({
|
||||||
|
blur_radius: BLUR_RADIUS,
|
||||||
|
vertical: true,
|
||||||
|
}));
|
||||||
|
widget.add_effect(new Shell.BlurEffect({
|
||||||
|
blur_radius: BLUR_RADIUS,
|
||||||
|
brightness: BLUR_BRIGHTNESS,
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateBackgrounds() {
|
_updateBackgrounds() {
|
||||||
|
@ -95,6 +95,7 @@ libshell_public_headers = [
|
|||||||
'shell-app.h',
|
'shell-app.h',
|
||||||
'shell-app-system.h',
|
'shell-app-system.h',
|
||||||
'shell-app-usage.h',
|
'shell-app-usage.h',
|
||||||
|
'shell-blur-effect.h',
|
||||||
'shell-embedded-window.h',
|
'shell-embedded-window.h',
|
||||||
'shell-glsl-effect.h',
|
'shell-glsl-effect.h',
|
||||||
'shell-gtk-embed.h',
|
'shell-gtk-embed.h',
|
||||||
@ -129,6 +130,7 @@ libshell_sources = [
|
|||||||
'shell-app.c',
|
'shell-app.c',
|
||||||
'shell-app-system.c',
|
'shell-app-system.c',
|
||||||
'shell-app-usage.c',
|
'shell-app-usage.c',
|
||||||
|
'shell-blur-effect.c',
|
||||||
'shell-embedded-window.c',
|
'shell-embedded-window.c',
|
||||||
'shell-embedded-window-private.h',
|
'shell-embedded-window-private.h',
|
||||||
'shell-global.c',
|
'shell-global.c',
|
||||||
|
488
src/shell-blur-effect.c
Normal file
488
src/shell-blur-effect.c
Normal file
@ -0,0 +1,488 @@
|
|||||||
|
/* shell-blur-effect.c
|
||||||
|
*
|
||||||
|
* Copyright 2019 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "shell-blur-effect.h"
|
||||||
|
|
||||||
|
static const gchar *gaussian_blur_glsl_declarations =
|
||||||
|
"uniform float blur_radius; \n"
|
||||||
|
"uniform float brightness; \n"
|
||||||
|
"uniform float pixel_step; \n"
|
||||||
|
"uniform int vertical; \n"
|
||||||
|
" \n"
|
||||||
|
"float gaussian (float sigma, float x) { \n"
|
||||||
|
" return exp ( - (x * x) / (2.0 * sigma * sigma)); \n"
|
||||||
|
"} \n"
|
||||||
|
" \n";
|
||||||
|
|
||||||
|
static const gchar *gaussian_blur_glsl =
|
||||||
|
" float radius = blur_radius * 2.30348; \n"
|
||||||
|
" float total = 0.0; \n"
|
||||||
|
" vec4 ret = vec4 (0); \n"
|
||||||
|
" vec2 uv = vec2(cogl_tex_coord.st); \n"
|
||||||
|
" \n"
|
||||||
|
" int half_radius = max(int(radius / 2.0), 1); \n"
|
||||||
|
" \n"
|
||||||
|
" if (vertical != 0) { \n"
|
||||||
|
" for (int y = -half_radius; y < half_radius; y++) { \n"
|
||||||
|
" float fy = gaussian (radius / 2.0, float(y)); \n"
|
||||||
|
" float offset_y = float(y) * pixel_step; \n"
|
||||||
|
" \n"
|
||||||
|
" vec4 c = texture2D(cogl_sampler, uv + vec2(0.0, offset_y)); \n"
|
||||||
|
" total += fy; \n"
|
||||||
|
" ret += c * fy; \n"
|
||||||
|
" } \n"
|
||||||
|
" } else { \n"
|
||||||
|
" for (int x = -half_radius; x < half_radius; x++) { \n"
|
||||||
|
" float fx = gaussian (radius / 2.0, float(x)); \n"
|
||||||
|
" float offset_x = float(x) * pixel_step; \n"
|
||||||
|
" \n"
|
||||||
|
" vec4 c = texture2D(cogl_sampler, uv + vec2(offset_x, 0.0)); \n"
|
||||||
|
" total += fx; \n"
|
||||||
|
" ret += c * fx; \n"
|
||||||
|
" } \n"
|
||||||
|
" } \n"
|
||||||
|
" \n"
|
||||||
|
" cogl_texel = vec4 (ret / total); \n"
|
||||||
|
" cogl_texel.rgb *= brightness; \n";
|
||||||
|
|
||||||
|
#define DOWNSCALE_FACTOR 3.0
|
||||||
|
|
||||||
|
struct _ShellBlurEffect
|
||||||
|
{
|
||||||
|
ClutterOffscreenEffect parent_instance;
|
||||||
|
|
||||||
|
CoglPipeline *pipeline;
|
||||||
|
int blur_radius_uniform;
|
||||||
|
int brightness_uniform;
|
||||||
|
int pixel_step_uniform;
|
||||||
|
int vertical_uniform;
|
||||||
|
|
||||||
|
unsigned int tex_width;
|
||||||
|
unsigned int tex_height;
|
||||||
|
|
||||||
|
gboolean vertical;
|
||||||
|
float brightness;
|
||||||
|
int blur_radius;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (ShellBlurEffect, shell_blur_effect, CLUTTER_TYPE_OFFSCREEN_EFFECT)
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PROP_0,
|
||||||
|
PROP_BLUR_RADIUS,
|
||||||
|
PROP_BRIGHTNESS,
|
||||||
|
PROP_VERTICAL,
|
||||||
|
N_PROPS
|
||||||
|
};
|
||||||
|
|
||||||
|
static GParamSpec *properties [N_PROPS] = { NULL, };
|
||||||
|
|
||||||
|
static CoglPipeline*
|
||||||
|
create_pipeline (void)
|
||||||
|
{
|
||||||
|
static CoglPipeline *base_pipeline = NULL;
|
||||||
|
|
||||||
|
if (G_UNLIKELY (base_pipeline == NULL))
|
||||||
|
{
|
||||||
|
CoglSnippet *snippet;
|
||||||
|
CoglContext *ctx =
|
||||||
|
clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
||||||
|
|
||||||
|
base_pipeline = cogl_pipeline_new (ctx);
|
||||||
|
|
||||||
|
snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_LOOKUP,
|
||||||
|
gaussian_blur_glsl_declarations,
|
||||||
|
NULL);
|
||||||
|
cogl_snippet_set_replace (snippet, gaussian_blur_glsl);
|
||||||
|
cogl_pipeline_add_layer_snippet (base_pipeline, 0, snippet);
|
||||||
|
cogl_object_unref (snippet);
|
||||||
|
|
||||||
|
cogl_pipeline_set_layer_null_texture (base_pipeline, 0);
|
||||||
|
cogl_pipeline_set_layer_filters (base_pipeline,
|
||||||
|
0,
|
||||||
|
COGL_PIPELINE_FILTER_LINEAR,
|
||||||
|
COGL_PIPELINE_FILTER_LINEAR);
|
||||||
|
cogl_pipeline_set_layer_wrap_mode (base_pipeline,
|
||||||
|
0,
|
||||||
|
COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cogl_pipeline_copy (base_pipeline);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
shell_blur_effect_pre_paint (ClutterEffect *effect)
|
||||||
|
{
|
||||||
|
ShellBlurEffect *self = SHELL_BLUR_EFFECT (effect);
|
||||||
|
ClutterOffscreenEffect *offscreen_effect =
|
||||||
|
CLUTTER_OFFSCREEN_EFFECT (self);
|
||||||
|
gboolean success;
|
||||||
|
|
||||||
|
success = CLUTTER_EFFECT_CLASS (shell_blur_effect_parent_class)->pre_paint (effect);
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
CoglFramebuffer *offscreen;
|
||||||
|
CoglHandle texture;
|
||||||
|
|
||||||
|
texture = clutter_offscreen_effect_get_texture (offscreen_effect);
|
||||||
|
self->tex_width = cogl_texture_get_width (texture) * DOWNSCALE_FACTOR;
|
||||||
|
self->tex_height = cogl_texture_get_height (texture) * DOWNSCALE_FACTOR;
|
||||||
|
|
||||||
|
if (self->pixel_step_uniform > -1)
|
||||||
|
{
|
||||||
|
ClutterRect rect;
|
||||||
|
float pixel_step;
|
||||||
|
|
||||||
|
clutter_offscreen_effect_get_target_rect (CLUTTER_OFFSCREEN_EFFECT (self),
|
||||||
|
&rect);
|
||||||
|
if (self->vertical)
|
||||||
|
pixel_step = 1.f / rect.size.height;
|
||||||
|
else
|
||||||
|
pixel_step = 1.f / rect.size.width;
|
||||||
|
|
||||||
|
cogl_pipeline_set_uniform_1f (self->pipeline,
|
||||||
|
self->pixel_step_uniform,
|
||||||
|
pixel_step / DOWNSCALE_FACTOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self->blur_radius_uniform > -1)
|
||||||
|
{
|
||||||
|
cogl_pipeline_set_uniform_1f (self->pipeline,
|
||||||
|
self->blur_radius_uniform,
|
||||||
|
self->blur_radius / DOWNSCALE_FACTOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self->brightness_uniform > -1)
|
||||||
|
{
|
||||||
|
cogl_pipeline_set_uniform_1f (self->pipeline,
|
||||||
|
self->brightness_uniform,
|
||||||
|
self->brightness);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self->vertical_uniform > -1)
|
||||||
|
{
|
||||||
|
cogl_pipeline_set_uniform_1i (self->pipeline,
|
||||||
|
self->vertical_uniform,
|
||||||
|
self->vertical);
|
||||||
|
}
|
||||||
|
|
||||||
|
cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
|
||||||
|
|
||||||
|
/* Texture is downscaled, draw downscaled as well */
|
||||||
|
offscreen = cogl_get_draw_framebuffer ();
|
||||||
|
cogl_framebuffer_scale (offscreen,
|
||||||
|
1.0 / DOWNSCALE_FACTOR,
|
||||||
|
1.0 / DOWNSCALE_FACTOR,
|
||||||
|
0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
shell_blur_effect_paint_target (ClutterOffscreenEffect *effect)
|
||||||
|
{
|
||||||
|
ShellBlurEffect *self = SHELL_BLUR_EFFECT (effect);
|
||||||
|
CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer ();
|
||||||
|
ClutterActor *actor;
|
||||||
|
float blur_radius_offset_h;
|
||||||
|
float blur_radius_offset_v;
|
||||||
|
guint8 paint_opacity;
|
||||||
|
|
||||||
|
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (self));
|
||||||
|
paint_opacity = clutter_actor_get_paint_opacity (actor);
|
||||||
|
|
||||||
|
cogl_pipeline_set_color4ub (self->pipeline,
|
||||||
|
paint_opacity,
|
||||||
|
paint_opacity,
|
||||||
|
paint_opacity,
|
||||||
|
paint_opacity);
|
||||||
|
|
||||||
|
blur_radius_offset_h =
|
||||||
|
self->blur_radius / (float) self->tex_width / DOWNSCALE_FACTOR;
|
||||||
|
blur_radius_offset_v =
|
||||||
|
self->blur_radius / (float) self->tex_height / DOWNSCALE_FACTOR;
|
||||||
|
|
||||||
|
cogl_framebuffer_draw_textured_rectangle (framebuffer,
|
||||||
|
self->pipeline,
|
||||||
|
0, 0,
|
||||||
|
self->tex_width,
|
||||||
|
self->tex_height,
|
||||||
|
blur_radius_offset_h,
|
||||||
|
blur_radius_offset_v,
|
||||||
|
1.f - blur_radius_offset_h,
|
||||||
|
1.f - blur_radius_offset_v);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
shell_blur_effect_post_paint (ClutterEffect *effect)
|
||||||
|
{
|
||||||
|
CoglFramebuffer *offscreen = cogl_get_draw_framebuffer ();
|
||||||
|
|
||||||
|
cogl_framebuffer_scale (offscreen,
|
||||||
|
DOWNSCALE_FACTOR,
|
||||||
|
DOWNSCALE_FACTOR,
|
||||||
|
0.f);
|
||||||
|
|
||||||
|
CLUTTER_EFFECT_CLASS (shell_blur_effect_parent_class)->post_paint (effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
static CoglTexture*
|
||||||
|
shell_blur_effect_create_texture (ClutterOffscreenEffect *effect,
|
||||||
|
float width,
|
||||||
|
float height)
|
||||||
|
{
|
||||||
|
CoglContext *ctx =
|
||||||
|
clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
||||||
|
|
||||||
|
return cogl_texture_2d_new_with_size (ctx, width / 2.0, height / 2.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
shell_blur_effect_modify_paint_volume (ClutterEffect *effect,
|
||||||
|
ClutterPaintVolume *volume)
|
||||||
|
{
|
||||||
|
ShellBlurEffect *self = SHELL_BLUR_EFFECT (effect);
|
||||||
|
ClutterVertex origin;
|
||||||
|
float width;
|
||||||
|
float height;
|
||||||
|
|
||||||
|
clutter_paint_volume_get_origin (volume, &origin);
|
||||||
|
width = clutter_paint_volume_get_width (volume);
|
||||||
|
height = clutter_paint_volume_get_height (volume);
|
||||||
|
|
||||||
|
if (self->vertical)
|
||||||
|
{
|
||||||
|
origin.y -= self->blur_radius;
|
||||||
|
height += 2 * self->blur_radius;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
origin.x -= self->blur_radius;
|
||||||
|
width += 2 * self->blur_radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
clutter_paint_volume_set_origin (volume, &origin);
|
||||||
|
clutter_paint_volume_set_width (volume, width);
|
||||||
|
clutter_paint_volume_set_height (volume, height);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
shell_blur_effect_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
ShellBlurEffect *self = (ShellBlurEffect *)object;
|
||||||
|
|
||||||
|
g_clear_pointer (&self->pipeline, cogl_object_unref);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (shell_blur_effect_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
shell_blur_effect_get_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
ShellBlurEffect *self = SHELL_BLUR_EFFECT (object);
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_BLUR_RADIUS:
|
||||||
|
g_value_set_int (value, self->blur_radius);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_BRIGHTNESS:
|
||||||
|
g_value_set_int (value, self->brightness);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_VERTICAL:
|
||||||
|
g_value_set_boolean (value, self->vertical);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
shell_blur_effect_set_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
ShellBlurEffect *self = SHELL_BLUR_EFFECT (object);
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_BLUR_RADIUS:
|
||||||
|
shell_blur_effect_set_blur_radius (self, g_value_get_int (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_BRIGHTNESS:
|
||||||
|
shell_blur_effect_set_brightness (self, g_value_get_float (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_VERTICAL:
|
||||||
|
shell_blur_effect_set_vertical (self, g_value_get_boolean (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
shell_blur_effect_class_init (ShellBlurEffectClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
ClutterEffectClass *effect_class = CLUTTER_EFFECT_CLASS (klass);
|
||||||
|
ClutterOffscreenEffectClass *offscreen_class =
|
||||||
|
CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->finalize = shell_blur_effect_finalize;
|
||||||
|
object_class->get_property = shell_blur_effect_get_property;
|
||||||
|
object_class->set_property = shell_blur_effect_set_property;
|
||||||
|
|
||||||
|
effect_class->pre_paint = shell_blur_effect_pre_paint;
|
||||||
|
effect_class->post_paint = shell_blur_effect_post_paint;
|
||||||
|
effect_class->modify_paint_volume = shell_blur_effect_modify_paint_volume;
|
||||||
|
|
||||||
|
offscreen_class->paint_target = shell_blur_effect_paint_target;
|
||||||
|
offscreen_class->create_texture = shell_blur_effect_create_texture;
|
||||||
|
|
||||||
|
properties[PROP_BLUR_RADIUS] =
|
||||||
|
g_param_spec_int ("blur-radius",
|
||||||
|
"Blur radius",
|
||||||
|
"Blur radius",
|
||||||
|
0, G_MAXINT, 0,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
|
properties[PROP_BRIGHTNESS] =
|
||||||
|
g_param_spec_float ("brightness",
|
||||||
|
"Brightness",
|
||||||
|
"Brightness",
|
||||||
|
0.f, 1.f, 1.f,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
|
properties[PROP_VERTICAL] =
|
||||||
|
g_param_spec_boolean ("vertical",
|
||||||
|
"Vertical",
|
||||||
|
"Whether the blur is vertical or horizontal",
|
||||||
|
FALSE,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
|
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
shell_blur_effect_init (ShellBlurEffect *self)
|
||||||
|
{
|
||||||
|
self->blur_radius = 0;
|
||||||
|
self->brightness = 1.f;
|
||||||
|
self->vertical = FALSE;
|
||||||
|
self->pipeline = create_pipeline ();
|
||||||
|
|
||||||
|
self->blur_radius_uniform =
|
||||||
|
cogl_pipeline_get_uniform_location (self->pipeline, "blur_radius");
|
||||||
|
self->brightness_uniform =
|
||||||
|
cogl_pipeline_get_uniform_location (self->pipeline, "brightness");
|
||||||
|
self->pixel_step_uniform =
|
||||||
|
cogl_pipeline_get_uniform_location (self->pipeline, "pixel_step");
|
||||||
|
self->vertical_uniform =
|
||||||
|
cogl_pipeline_get_uniform_location (self->pipeline, "vertical");
|
||||||
|
}
|
||||||
|
|
||||||
|
ShellBlurEffect *
|
||||||
|
shell_blur_effect_new (void)
|
||||||
|
{
|
||||||
|
return g_object_new (SHELL_TYPE_BLUR_EFFECT, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
shell_blur_effect_get_blur_radius (ShellBlurEffect *self)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (SHELL_IS_BLUR_EFFECT (self), -1);
|
||||||
|
|
||||||
|
return self->blur_radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
shell_blur_effect_set_blur_radius (ShellBlurEffect *self,
|
||||||
|
int radius)
|
||||||
|
{
|
||||||
|
g_return_if_fail (SHELL_IS_BLUR_EFFECT (self));
|
||||||
|
|
||||||
|
if (self->blur_radius == radius)
|
||||||
|
return;
|
||||||
|
|
||||||
|
self->blur_radius = radius;
|
||||||
|
clutter_effect_queue_repaint (CLUTTER_EFFECT (self));
|
||||||
|
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_BLUR_RADIUS]);
|
||||||
|
}
|
||||||
|
|
||||||
|
float
|
||||||
|
shell_blur_effect_get_brightness (ShellBlurEffect *self)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (SHELL_IS_BLUR_EFFECT (self), FALSE);
|
||||||
|
|
||||||
|
return self->brightness;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
shell_blur_effect_set_brightness (ShellBlurEffect *self,
|
||||||
|
float brightness)
|
||||||
|
{
|
||||||
|
g_return_if_fail (SHELL_IS_BLUR_EFFECT (self));
|
||||||
|
|
||||||
|
if (self->brightness == brightness)
|
||||||
|
return;
|
||||||
|
|
||||||
|
self->brightness = brightness;
|
||||||
|
clutter_effect_queue_repaint (CLUTTER_EFFECT (self));
|
||||||
|
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_BRIGHTNESS]);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
shell_blur_effect_get_vertical (ShellBlurEffect *self)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (SHELL_IS_BLUR_EFFECT (self), FALSE);
|
||||||
|
|
||||||
|
return self->vertical;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
shell_blur_effect_set_vertical (ShellBlurEffect *self,
|
||||||
|
gboolean vertical)
|
||||||
|
{
|
||||||
|
g_return_if_fail (SHELL_IS_BLUR_EFFECT (self));
|
||||||
|
|
||||||
|
if (self->vertical == vertical)
|
||||||
|
return;
|
||||||
|
|
||||||
|
self->vertical = vertical;
|
||||||
|
clutter_effect_queue_repaint (CLUTTER_EFFECT (self));
|
||||||
|
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_VERTICAL]);
|
||||||
|
}
|
45
src/shell-blur-effect.h
Normal file
45
src/shell-blur-effect.h
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/* shell-blur-effect.h
|
||||||
|
*
|
||||||
|
* Copyright 2019 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <clutter/clutter.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define SHELL_TYPE_BLUR_EFFECT (shell_blur_effect_get_type())
|
||||||
|
|
||||||
|
G_DECLARE_FINAL_TYPE (ShellBlurEffect, shell_blur_effect, SHELL, BLUR_EFFECT, ClutterOffscreenEffect)
|
||||||
|
|
||||||
|
ShellBlurEffect *shell_blur_effect_new (void);
|
||||||
|
|
||||||
|
int shell_blur_effect_get_blur_radius (ShellBlurEffect *self);
|
||||||
|
void shell_blur_effect_set_blur_radius (ShellBlurEffect *self,
|
||||||
|
int radius);
|
||||||
|
|
||||||
|
float shell_blur_effect_get_brightness (ShellBlurEffect *self);
|
||||||
|
void shell_blur_effect_set_brightness (ShellBlurEffect *self,
|
||||||
|
float brightness);
|
||||||
|
|
||||||
|
gboolean shell_blur_effect_get_vertical (ShellBlurEffect *self);
|
||||||
|
void shell_blur_effect_set_vertical (ShellBlurEffect *self,
|
||||||
|
gboolean vertical);
|
||||||
|
|
||||||
|
G_END_DECLS
|
Loading…
Reference in New Issue
Block a user