blur-effect: Use ClutterBlurNode
With ClutterBlurNode available, we can remove our own implementation and delegate the blur shader and framebuffers. This simply replaces the pair of layer nodes (vblur and hblur) with a ClutterBlurNode, and removes all dead code. Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1528>
This commit is contained in:
parent
52ccf86599
commit
f7019bdd0d
@ -26,7 +26,7 @@
|
|||||||
* SECTION:shell-blur-effect
|
* SECTION:shell-blur-effect
|
||||||
* @short_description: Blur effect for actors
|
* @short_description: Blur effect for actors
|
||||||
*
|
*
|
||||||
* #ShellBlurEffect is a moderately fast gaussian blur implementation. It also has
|
* #ShellBlurEffect is a blur implementation based on Clutter. It also has
|
||||||
* an optional brightness property.
|
* an optional brightness property.
|
||||||
*
|
*
|
||||||
* # Modes
|
* # Modes
|
||||||
@ -38,89 +38,8 @@
|
|||||||
* @SHELL_BLUR_MODE_BACKGROUND can be computationally expensive, since the contents
|
* @SHELL_BLUR_MODE_BACKGROUND can be computationally expensive, since the contents
|
||||||
* beneath the actor cannot be cached, so beware of the performance implications
|
* beneath the actor cannot be cached, so beware of the performance implications
|
||||||
* of using this blur mode.
|
* of using this blur mode.
|
||||||
*
|
|
||||||
* # Optimizations
|
|
||||||
*
|
|
||||||
* There are a number of optimizations in place to make this blur implementation
|
|
||||||
* real-time. All in all, the implementation performs best when using large
|
|
||||||
* blur-radii that allow downscaling the texture to smaller sizes, at small
|
|
||||||
* radii where no downscaling is possible this can easily halve the framerate.
|
|
||||||
*
|
|
||||||
* ## Multipass
|
|
||||||
*
|
|
||||||
* It is implemented in 2 passes: vertical and horizontal.
|
|
||||||
*
|
|
||||||
* ## Downscaling
|
|
||||||
*
|
|
||||||
* #ShellBlurEffect uses dynamic downscaling to speed up blurring. Downscaling
|
|
||||||
* happens in factors of 2 (the image is downscaled either by 2, 4, 8, 16, …) and
|
|
||||||
* depends on the blur radius, the actor size, among others.
|
|
||||||
*
|
|
||||||
* The actor is drawn into a downscaled framebuffer; the blur passes are applied
|
|
||||||
* on the downscaled actor contents; and finally, the blurred contents are drawn
|
|
||||||
* upscaled again.
|
|
||||||
*
|
|
||||||
* ## Hardware Interpolation
|
|
||||||
*
|
|
||||||
* This blur implementation cuts down the number of sampling operations by
|
|
||||||
* exploiting the hardware interpolation that is performed when sampling between
|
|
||||||
* pixel boundaries. This technique is described at:
|
|
||||||
*
|
|
||||||
* http://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/
|
|
||||||
*
|
|
||||||
* ## Incremental gauss-factor calculation
|
|
||||||
*
|
|
||||||
* The kernel values for the gaussian kernel are computed incrementally instead
|
|
||||||
* of running the expensive calculations multiple times inside the blur shader.
|
|
||||||
* The implementation is based on the algorithm presented by K. Turkowski in
|
|
||||||
* GPU Gems 3, chapter 40:
|
|
||||||
*
|
|
||||||
* https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch40.html
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const gchar *gaussian_blur_glsl_declarations =
|
|
||||||
"uniform float sigma; \n"
|
|
||||||
"uniform float pixel_step; \n"
|
|
||||||
"uniform int vertical; \n";
|
|
||||||
|
|
||||||
static const gchar *gaussian_blur_glsl =
|
|
||||||
" int horizontal = 1 - vertical; \n"
|
|
||||||
" \n"
|
|
||||||
" vec2 uv = vec2 (cogl_tex_coord.st); \n"
|
|
||||||
" \n"
|
|
||||||
" vec3 gauss_coefficient; \n"
|
|
||||||
" gauss_coefficient.x = 1.0 / (sqrt (2.0 * 3.14159265) * sigma); \n"
|
|
||||||
" gauss_coefficient.y = exp (-0.5 / (sigma * sigma)); \n"
|
|
||||||
" gauss_coefficient.z = gauss_coefficient.y * gauss_coefficient.y; \n"
|
|
||||||
" \n"
|
|
||||||
" float gauss_coefficient_total = gauss_coefficient.x; \n"
|
|
||||||
" \n"
|
|
||||||
" vec4 ret = texture2D (cogl_sampler, uv) * gauss_coefficient.x; \n"
|
|
||||||
" gauss_coefficient.xy *= gauss_coefficient.yz; \n"
|
|
||||||
" \n"
|
|
||||||
" int n_steps = int (ceil (3 * sigma)); \n"
|
|
||||||
" \n"
|
|
||||||
" for (int i = 1; i < n_steps; i += 2) { \n"
|
|
||||||
" float coefficient_subtotal = gauss_coefficient.x; \n"
|
|
||||||
" gauss_coefficient.xy *= gauss_coefficient.yz; \n"
|
|
||||||
" coefficient_subtotal += gauss_coefficient.x; \n"
|
|
||||||
" \n"
|
|
||||||
" float gauss_ratio = gauss_coefficient.x / coefficient_subtotal; \n"
|
|
||||||
" \n"
|
|
||||||
" float foffset = float (i) + gauss_ratio; \n"
|
|
||||||
" vec2 offset = vec2 (foffset * pixel_step * float (horizontal), \n"
|
|
||||||
" foffset * pixel_step * float (vertical)); \n"
|
|
||||||
" \n"
|
|
||||||
" ret += texture2D (cogl_sampler, uv + offset) * coefficient_subtotal; \n"
|
|
||||||
" ret += texture2D (cogl_sampler, uv - offset) * coefficient_subtotal; \n"
|
|
||||||
" \n"
|
|
||||||
" gauss_coefficient_total += 2.0 * coefficient_subtotal; \n"
|
|
||||||
" gauss_coefficient.xy *= gauss_coefficient.yz; \n"
|
|
||||||
" } \n"
|
|
||||||
" \n"
|
|
||||||
" cogl_texel = ret / gauss_coefficient_total; \n";
|
|
||||||
|
|
||||||
static const gchar *brightness_glsl_declarations =
|
static const gchar *brightness_glsl_declarations =
|
||||||
"uniform float brightness; \n";
|
"uniform float brightness; \n";
|
||||||
|
|
||||||
@ -130,12 +49,6 @@ static const gchar *brightness_glsl =
|
|||||||
#define MIN_DOWNSCALE_SIZE 256.f
|
#define MIN_DOWNSCALE_SIZE 256.f
|
||||||
#define MAX_SIGMA 6.f
|
#define MAX_SIGMA 6.f
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
VERTICAL,
|
|
||||||
HORIZONTAL,
|
|
||||||
} BlurType;
|
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
ACTOR_PAINTED = 1 << 0,
|
ACTOR_PAINTED = 1 << 0,
|
||||||
@ -149,23 +62,12 @@ typedef struct
|
|||||||
CoglTexture *texture;
|
CoglTexture *texture;
|
||||||
} FramebufferData;
|
} FramebufferData;
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
FramebufferData data;
|
|
||||||
BlurType type;
|
|
||||||
int sigma_uniform;
|
|
||||||
int pixel_step_uniform;
|
|
||||||
int vertical_uniform;
|
|
||||||
} BlurData;
|
|
||||||
|
|
||||||
struct _ShellBlurEffect
|
struct _ShellBlurEffect
|
||||||
{
|
{
|
||||||
ClutterEffect parent_instance;
|
ClutterEffect parent_instance;
|
||||||
|
|
||||||
ClutterActor *actor;
|
ClutterActor *actor;
|
||||||
|
|
||||||
BlurData blur[2];
|
|
||||||
|
|
||||||
unsigned int tex_width;
|
unsigned int tex_width;
|
||||||
unsigned int tex_height;
|
unsigned int tex_height;
|
||||||
|
|
||||||
@ -219,29 +121,6 @@ create_base_pipeline (void)
|
|||||||
return cogl_pipeline_copy (base_pipeline);
|
return cogl_pipeline_copy (base_pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
static CoglPipeline*
|
|
||||||
create_blur_pipeline (void)
|
|
||||||
{
|
|
||||||
static CoglPipeline *blur_pipeline = NULL;
|
|
||||||
|
|
||||||
if (G_UNLIKELY (blur_pipeline == NULL))
|
|
||||||
{
|
|
||||||
CoglSnippet *snippet;
|
|
||||||
|
|
||||||
blur_pipeline = create_base_pipeline ();
|
|
||||||
|
|
||||||
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 (blur_pipeline, 0, snippet);
|
|
||||||
cogl_object_unref (snippet);
|
|
||||||
}
|
|
||||||
|
|
||||||
return cogl_pipeline_copy (blur_pipeline);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static CoglPipeline*
|
static CoglPipeline*
|
||||||
create_brightness_pipeline (void)
|
create_brightness_pipeline (void)
|
||||||
{
|
{
|
||||||
@ -263,59 +142,17 @@ create_brightness_pipeline (void)
|
|||||||
return cogl_pipeline_copy (brightness_pipeline);
|
return cogl_pipeline_copy (brightness_pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
setup_blur (BlurData *blur,
|
|
||||||
BlurType type)
|
|
||||||
{
|
|
||||||
blur->type = type;
|
|
||||||
blur->data.pipeline = create_blur_pipeline ();
|
|
||||||
|
|
||||||
blur->sigma_uniform =
|
|
||||||
cogl_pipeline_get_uniform_location (blur->data.pipeline, "sigma");
|
|
||||||
blur->pixel_step_uniform =
|
|
||||||
cogl_pipeline_get_uniform_location (blur->data.pipeline, "pixel_step");
|
|
||||||
blur->vertical_uniform =
|
|
||||||
cogl_pipeline_get_uniform_location (blur->data.pipeline, "vertical");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_blur_uniforms (ShellBlurEffect *self,
|
update_brightness (ShellBlurEffect *self,
|
||||||
BlurData *blur)
|
uint8_t paint_opacity)
|
||||||
{
|
{
|
||||||
gboolean is_vertical = blur->type == VERTICAL;
|
cogl_pipeline_set_color4ub (self->brightness_fb.pipeline,
|
||||||
|
paint_opacity,
|
||||||
|
paint_opacity,
|
||||||
|
paint_opacity,
|
||||||
|
paint_opacity);
|
||||||
|
|
||||||
if (blur->pixel_step_uniform > -1)
|
|
||||||
{
|
|
||||||
float pixel_step;
|
|
||||||
|
|
||||||
if (is_vertical)
|
|
||||||
pixel_step = 1.f / cogl_texture_get_height (blur->data.texture);
|
|
||||||
else
|
|
||||||
pixel_step = 1.f / cogl_texture_get_width (blur->data.texture);
|
|
||||||
|
|
||||||
cogl_pipeline_set_uniform_1f (blur->data.pipeline,
|
|
||||||
blur->pixel_step_uniform,
|
|
||||||
pixel_step);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (blur->sigma_uniform > -1)
|
|
||||||
{
|
|
||||||
cogl_pipeline_set_uniform_1f (blur->data.pipeline,
|
|
||||||
blur->sigma_uniform,
|
|
||||||
self->sigma / self->downscale_factor);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (blur->vertical_uniform > -1)
|
|
||||||
{
|
|
||||||
cogl_pipeline_set_uniform_1i (blur->data.pipeline,
|
|
||||||
blur->vertical_uniform,
|
|
||||||
is_vertical);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
update_brightness_uniform (ShellBlurEffect *self)
|
|
||||||
{
|
|
||||||
if (self->brightness_uniform > -1)
|
if (self->brightness_uniform > -1)
|
||||||
{
|
{
|
||||||
cogl_pipeline_set_uniform_1f (self->brightness_fb.pipeline,
|
cogl_pipeline_set_uniform_1f (self->brightness_fb.pipeline,
|
||||||
@ -412,26 +249,6 @@ update_brightness_fbo (ShellBlurEffect *self,
|
|||||||
downscale_factor);
|
downscale_factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
update_blur_fbo (ShellBlurEffect *self,
|
|
||||||
BlurData *blur,
|
|
||||||
unsigned int width,
|
|
||||||
unsigned int height,
|
|
||||||
float downscale_factor)
|
|
||||||
{
|
|
||||||
if (self->tex_width == width &&
|
|
||||||
self->tex_height == height &&
|
|
||||||
self->downscale_factor == downscale_factor &&
|
|
||||||
blur->data.framebuffer)
|
|
||||||
{
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return update_fbo (&blur->data,
|
|
||||||
width, height,
|
|
||||||
downscale_factor);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
update_background_fbo (ShellBlurEffect *self,
|
update_background_fbo (ShellBlurEffect *self,
|
||||||
unsigned int width,
|
unsigned int width,
|
||||||
@ -496,8 +313,6 @@ shell_blur_effect_set_actor (ClutterActorMeta *meta,
|
|||||||
clear_framebuffer_data (&self->actor_fb);
|
clear_framebuffer_data (&self->actor_fb);
|
||||||
clear_framebuffer_data (&self->background_fb);
|
clear_framebuffer_data (&self->background_fb);
|
||||||
clear_framebuffer_data (&self->brightness_fb);
|
clear_framebuffer_data (&self->brightness_fb);
|
||||||
clear_framebuffer_data (&self->blur[VERTICAL].data);
|
|
||||||
clear_framebuffer_data (&self->blur[HORIZONTAL].data);
|
|
||||||
|
|
||||||
/* we keep a back pointer here, to avoid going through the ActorMeta */
|
/* we keep a back pointer here, to avoid going through the ActorMeta */
|
||||||
self->actor = clutter_actor_meta_get_actor (meta);
|
self->actor = clutter_actor_meta_get_actor (meta);
|
||||||
@ -543,7 +358,8 @@ update_actor_box (ShellBlurEffect *self,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
add_blurred_pipeline (ShellBlurEffect *self,
|
add_blurred_pipeline (ShellBlurEffect *self,
|
||||||
ClutterPaintNode *node)
|
ClutterPaintNode *node,
|
||||||
|
uint8_t paint_opacity)
|
||||||
{
|
{
|
||||||
g_autoptr (ClutterPaintNode) pipeline_node = NULL;
|
g_autoptr (ClutterPaintNode) pipeline_node = NULL;
|
||||||
float width, height;
|
float width, height;
|
||||||
@ -553,7 +369,7 @@ add_blurred_pipeline (ShellBlurEffect *self,
|
|||||||
*/
|
*/
|
||||||
clutter_actor_get_size (self->actor, &width, &height);
|
clutter_actor_get_size (self->actor, &width, &height);
|
||||||
|
|
||||||
update_brightness_uniform (self);
|
update_brightness (self, paint_opacity);
|
||||||
|
|
||||||
pipeline_node = clutter_pipeline_node_new (self->brightness_fb.pipeline);
|
pipeline_node = clutter_pipeline_node_new (self->brightness_fb.pipeline);
|
||||||
clutter_paint_node_set_static_name (pipeline_node, "ShellBlurEffect (final)");
|
clutter_paint_node_set_static_name (pipeline_node, "ShellBlurEffect (final)");
|
||||||
@ -573,26 +389,13 @@ create_blur_nodes (ShellBlurEffect *self,
|
|||||||
uint8_t paint_opacity)
|
uint8_t paint_opacity)
|
||||||
{
|
{
|
||||||
g_autoptr (ClutterPaintNode) brightness_node = NULL;
|
g_autoptr (ClutterPaintNode) brightness_node = NULL;
|
||||||
g_autoptr (ClutterPaintNode) hblur_node = NULL;
|
g_autoptr (ClutterPaintNode) blur_node = NULL;
|
||||||
g_autoptr (ClutterPaintNode) vblur_node = NULL;
|
|
||||||
BlurData *vblur;
|
|
||||||
BlurData *hblur;
|
|
||||||
float width;
|
float width;
|
||||||
float height;
|
float height;
|
||||||
|
|
||||||
vblur = &self->blur[VERTICAL];
|
|
||||||
hblur = &self->blur[HORIZONTAL];
|
|
||||||
|
|
||||||
clutter_actor_get_size (self->actor, &width, &height);
|
clutter_actor_get_size (self->actor, &width, &height);
|
||||||
|
|
||||||
update_brightness_uniform (self);
|
update_brightness (self, paint_opacity);
|
||||||
|
|
||||||
cogl_pipeline_set_color4ub (self->brightness_fb.pipeline,
|
|
||||||
paint_opacity,
|
|
||||||
paint_opacity,
|
|
||||||
paint_opacity,
|
|
||||||
paint_opacity);
|
|
||||||
|
|
||||||
brightness_node = clutter_layer_node_new_to_framebuffer (self->brightness_fb.framebuffer,
|
brightness_node = clutter_layer_node_new_to_framebuffer (self->brightness_fb.framebuffer,
|
||||||
self->brightness_fb.pipeline);
|
self->brightness_fb.pipeline);
|
||||||
clutter_paint_node_set_static_name (brightness_node, "ShellBlurEffect (brightness)");
|
clutter_paint_node_set_static_name (brightness_node, "ShellBlurEffect (brightness)");
|
||||||
@ -603,46 +406,21 @@ create_blur_nodes (ShellBlurEffect *self,
|
|||||||
width, height,
|
width, height,
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Horizontal pass:
|
blur_node = clutter_blur_node_new (self->tex_width / self->downscale_factor,
|
||||||
*
|
self->tex_height / self->downscale_factor,
|
||||||
* This layer node contains the vertically blurred image; draw the it using the
|
self->sigma / self->downscale_factor);
|
||||||
* horizontal blur pipeline.
|
clutter_paint_node_set_static_name (blur_node, "ShellBlurEffect (blur)");
|
||||||
*/
|
clutter_paint_node_add_child (brightness_node, blur_node);
|
||||||
update_blur_uniforms (self, hblur);
|
clutter_paint_node_add_rectangle (blur_node,
|
||||||
|
|
||||||
hblur_node = clutter_layer_node_new_to_framebuffer (hblur->data.framebuffer,
|
|
||||||
hblur->data.pipeline);
|
|
||||||
clutter_paint_node_set_static_name (hblur_node, "ShellBlurEffect (horizontal pass)");
|
|
||||||
clutter_paint_node_add_child (brightness_node, hblur_node);
|
|
||||||
clutter_paint_node_add_rectangle (hblur_node,
|
|
||||||
&(ClutterActorBox) {
|
&(ClutterActorBox) {
|
||||||
0.f, 0.f,
|
0.f, 0.f,
|
||||||
cogl_texture_get_width (self->brightness_fb.texture),
|
cogl_texture_get_width (self->brightness_fb.texture),
|
||||||
cogl_texture_get_height (self->brightness_fb.texture),
|
cogl_texture_get_height (self->brightness_fb.texture),
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Vertical pass:
|
|
||||||
*
|
|
||||||
* Draw the actor contents into the vblur framebuffer using the vertical
|
|
||||||
* blur pipeline, which will output a vertically blurred image that will
|
|
||||||
* be used by the parent node (hblur_node).
|
|
||||||
*/
|
|
||||||
update_blur_uniforms (self, vblur);
|
|
||||||
|
|
||||||
vblur_node = clutter_layer_node_new_to_framebuffer (vblur->data.framebuffer,
|
|
||||||
vblur->data.pipeline);
|
|
||||||
clutter_paint_node_set_static_name (vblur_node, "ShellBlurEffect (vertical pass)");
|
|
||||||
clutter_paint_node_add_child (hblur_node, vblur_node);
|
|
||||||
clutter_paint_node_add_rectangle (vblur_node,
|
|
||||||
&(ClutterActorBox) {
|
|
||||||
0.f, 0.f,
|
|
||||||
cogl_texture_get_width (hblur->data.texture),
|
|
||||||
cogl_texture_get_height (hblur->data.texture)
|
|
||||||
});
|
|
||||||
|
|
||||||
self->cache_flags |= BLUR_APPLIED;
|
self->cache_flags |= BLUR_APPLIED;
|
||||||
|
|
||||||
return g_steal_pointer (&vblur_node);
|
return g_steal_pointer (&blur_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -706,10 +484,7 @@ update_framebuffers (ShellBlurEffect *self,
|
|||||||
|
|
||||||
downscale_factor = calculate_downscale_factor (width, height, self->sigma);
|
downscale_factor = calculate_downscale_factor (width, height, self->sigma);
|
||||||
|
|
||||||
updated =
|
updated = update_actor_fbo (self, width, height, downscale_factor) &&
|
||||||
update_actor_fbo (self, width, height, downscale_factor) &&
|
|
||||||
update_blur_fbo (self, &self->blur[VERTICAL], width, height, downscale_factor) &&
|
|
||||||
update_blur_fbo (self, &self->blur[HORIZONTAL], width, height, downscale_factor) &&
|
|
||||||
update_brightness_fbo (self, width, height, downscale_factor);
|
update_brightness_fbo (self, width, height, downscale_factor);
|
||||||
|
|
||||||
if (self->mode == SHELL_BLUR_MODE_BACKGROUND)
|
if (self->mode == SHELL_BLUR_MODE_BACKGROUND)
|
||||||
@ -831,6 +606,17 @@ shell_blur_effect_paint_node (ClutterEffect *effect,
|
|||||||
{
|
{
|
||||||
g_autoptr (ClutterPaintNode) blur_node = NULL;
|
g_autoptr (ClutterPaintNode) blur_node = NULL;
|
||||||
|
|
||||||
|
switch (self->mode)
|
||||||
|
{
|
||||||
|
case SHELL_BLUR_MODE_ACTOR:
|
||||||
|
paint_opacity = clutter_actor_get_paint_opacity (self->actor);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SHELL_BLUR_MODE_BACKGROUND:
|
||||||
|
paint_opacity = 255;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (needs_repaint (self, flags))
|
if (needs_repaint (self, flags))
|
||||||
{
|
{
|
||||||
ClutterActorBox source_actor_box;
|
ClutterActorBox source_actor_box;
|
||||||
@ -843,17 +629,15 @@ shell_blur_effect_paint_node (ClutterEffect *effect,
|
|||||||
if (!update_framebuffers (self, paint_context, &source_actor_box))
|
if (!update_framebuffers (self, paint_context, &source_actor_box))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
blur_node = create_blur_nodes (self, node, paint_opacity);
|
||||||
|
|
||||||
switch (self->mode)
|
switch (self->mode)
|
||||||
{
|
{
|
||||||
case SHELL_BLUR_MODE_ACTOR:
|
case SHELL_BLUR_MODE_ACTOR:
|
||||||
paint_opacity = clutter_actor_get_paint_opacity (self->actor);
|
|
||||||
|
|
||||||
blur_node = create_blur_nodes (self, node, paint_opacity);
|
|
||||||
paint_actor_offscreen (self, blur_node, flags);
|
paint_actor_offscreen (self, blur_node, flags);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SHELL_BLUR_MODE_BACKGROUND:
|
case SHELL_BLUR_MODE_BACKGROUND:
|
||||||
blur_node = create_blur_nodes (self, node, 255);
|
|
||||||
paint_background (self, blur_node, paint_context, &source_actor_box);
|
paint_background (self, blur_node, paint_context, &source_actor_box);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -861,7 +645,7 @@ shell_blur_effect_paint_node (ClutterEffect *effect,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Use the cached pipeline if no repaint is needed */
|
/* Use the cached pipeline if no repaint is needed */
|
||||||
add_blurred_pipeline (self, node);
|
add_blurred_pipeline (self, node, paint_opacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Background blur needs to paint the actor after painting the blurred
|
/* Background blur needs to paint the actor after painting the blurred
|
||||||
@ -895,14 +679,10 @@ shell_blur_effect_finalize (GObject *object)
|
|||||||
clear_framebuffer_data (&self->actor_fb);
|
clear_framebuffer_data (&self->actor_fb);
|
||||||
clear_framebuffer_data (&self->background_fb);
|
clear_framebuffer_data (&self->background_fb);
|
||||||
clear_framebuffer_data (&self->brightness_fb);
|
clear_framebuffer_data (&self->brightness_fb);
|
||||||
clear_framebuffer_data (&self->blur[VERTICAL].data);
|
|
||||||
clear_framebuffer_data (&self->blur[HORIZONTAL].data);
|
|
||||||
|
|
||||||
g_clear_pointer (&self->actor_fb.pipeline, cogl_object_unref);
|
g_clear_pointer (&self->actor_fb.pipeline, cogl_object_unref);
|
||||||
g_clear_pointer (&self->background_fb.pipeline, cogl_object_unref);
|
g_clear_pointer (&self->background_fb.pipeline, cogl_object_unref);
|
||||||
g_clear_pointer (&self->brightness_fb.pipeline, cogl_object_unref);
|
g_clear_pointer (&self->brightness_fb.pipeline, cogl_object_unref);
|
||||||
g_clear_pointer (&self->blur[VERTICAL].data.pipeline, cogl_object_unref);
|
|
||||||
g_clear_pointer (&self->blur[HORIZONTAL].data.pipeline, cogl_object_unref);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (shell_blur_effect_parent_class)->finalize (object);
|
G_OBJECT_CLASS (shell_blur_effect_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
@ -1013,9 +793,6 @@ shell_blur_effect_init (ShellBlurEffect *self)
|
|||||||
self->brightness_fb.pipeline = create_brightness_pipeline ();
|
self->brightness_fb.pipeline = create_brightness_pipeline ();
|
||||||
self->brightness_uniform =
|
self->brightness_uniform =
|
||||||
cogl_pipeline_get_uniform_location (self->brightness_fb.pipeline, "brightness");
|
cogl_pipeline_get_uniform_location (self->brightness_fb.pipeline, "brightness");
|
||||||
|
|
||||||
setup_blur (&self->blur[VERTICAL], VERTICAL);
|
|
||||||
setup_blur (&self->blur[HORIZONTAL], HORIZONTAL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ShellBlurEffect *
|
ShellBlurEffect *
|
||||||
|
Loading…
Reference in New Issue
Block a user