forked from Mirror/niri
feat(blur): reintroduce true blur, with x-ray config option
This commit is contained in:
28
README.md
28
README.md
@@ -21,8 +21,13 @@ the [original readme](./README_orig.md).
|
||||
Windows (both floating and tiling), as well as layer surfaces can have blur enabled on them. Blur needs to be enabled
|
||||
for each window / layer surface explicitly.
|
||||
|
||||
Currently, all windows will draw "optimized" or "x-ray" blur, which is rendered separately using only the `bottom` and
|
||||
`background` layer surfaces.
|
||||
Tiled windows will always draw "optimized" or "x-ray" blur, which is rendered from a shared texture using only the
|
||||
`bottom` and `background` layer surfaces, and is updated at a slower rate. Floating windows, as well as `top` or
|
||||
`overlay` layer surfaces will draw "true" blur by default instead, which is rendered using all available screen
|
||||
contents.
|
||||
|
||||
Note that true blur is rather expensive in terms of GPU load however, so an option exists to also have these surfaces
|
||||
draw `x-ray` blur instead.
|
||||
|
||||
To set global defaults for blur:
|
||||
|
||||
@@ -72,17 +77,20 @@ layer-rule {
|
||||
// note that this will require rendering the blurred surface twice, so if possible,
|
||||
// prefer using `geometry-corner-radius` instead, for performance reasons.
|
||||
ignore-alpha 0.45
|
||||
|
||||
// will render "x-ray" blur that is only based on `bottom` and `background` layer surfaces,
|
||||
// even if the window is floating. good for minimal GPU load.
|
||||
x-ray true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Caveats
|
||||
|
||||
- Enabling blur currently incurs a noticeable increase in GPU utilization on high frame rates (tested with 240hz)
|
||||
compared to other compositors with similar functionality (e.g. Hyprland). Investigating this will require some sort of
|
||||
[GPU profiling](https://github.com/Smithay/smithay/pull/1134).
|
||||
- There is currently no way to enable "true" blur for floating windows or top / overlay layer surfaces. The
|
||||
functionality exists in code, but is very slow / buggy at the moment.
|
||||
- True blur currently only works for horizontal monitor configurations. When using any sort of 90 or 270 degree
|
||||
transformations, only x-ray blur will be available.
|
||||
- True blur is rather performance intensive as of right now, since it renders itself on every frame. It is recommended
|
||||
to only enable it for surfaces that don't take up a lot of screen time (e.g. notifications, dialogs).
|
||||
- Blur is currently only possible to be enabled through the config. Implementing both
|
||||
[KDE blur](https://wayland.app/protocols/kde-blur) and
|
||||
[background effect](https://wayland.app/protocols/ext-background-effect-v1) is planned though.
|
||||
@@ -152,7 +160,7 @@ Since windows can be grouped on a per-tile basis, column-level tabbing is obsole
|
||||
options have been removed to improve maintainability. If you have any tabbed-column related options in your niri config,
|
||||
this fork will fail to parse it.
|
||||
|
||||
## Plans
|
||||
## Future Plans
|
||||
|
||||
As of right now, I am trying to keep this fork "as close to upstream as is reasonable", to allow for frequent rebasing
|
||||
without too many conflicts to solve.
|
||||
@@ -240,8 +248,6 @@ To use it, simply import the module it provides into your config:
|
||||
|
||||
# optional, if using home-manager
|
||||
home-manager = {
|
||||
# recommended, as the niri module from this fork overrides the upstream niri package
|
||||
useGlobalPkgs = true;
|
||||
users.my-username = {
|
||||
imports = [
|
||||
niri.homeManagerModules.default
|
||||
@@ -249,6 +255,8 @@ To use it, simply import the module it provides into your config:
|
||||
|
||||
wayland.windowManager.niri = {
|
||||
enable = true;
|
||||
# use the package from `programs.niri.package`, which is set by `niri.nixosModules.default`
|
||||
package = null;
|
||||
# fully declarative niri configuration; converted to kdl during rebuild
|
||||
#
|
||||
# - simple entries without arguments are declared as `name = [];`
|
||||
|
||||
@@ -345,6 +345,7 @@ pub struct Blur {
|
||||
pub radius: FloatOrInt<0, 1024>,
|
||||
pub noise: FloatOrInt<0, 1024>,
|
||||
pub ignore_alpha: FloatOrInt<0, 1>,
|
||||
pub x_ray: bool,
|
||||
}
|
||||
|
||||
impl Default for Blur {
|
||||
@@ -355,6 +356,7 @@ impl Default for Blur {
|
||||
radius: FloatOrInt(0.0),
|
||||
noise: FloatOrInt(0.0),
|
||||
ignore_alpha: FloatOrInt(0.0),
|
||||
x_ray: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -366,7 +368,7 @@ impl MergeWith<BlurRule> for Blur {
|
||||
self.on = false;
|
||||
}
|
||||
|
||||
merge_clone!((self, part), passes, radius, noise, ignore_alpha);
|
||||
merge_clone!((self, part), passes, radius, noise, ignore_alpha, x_ray);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -692,6 +694,8 @@ pub struct BlurRule {
|
||||
pub noise: Option<FloatOrInt<0, 1024>>,
|
||||
#[knuffel(child, unwrap(argument))]
|
||||
pub ignore_alpha: Option<FloatOrInt<0, 1>>,
|
||||
#[knuffel(child, unwrap(argument))]
|
||||
pub x_ray: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(knuffel::Decode, Debug, Default, Clone, Copy, PartialEq)]
|
||||
@@ -749,7 +753,7 @@ impl MergeWith<Self> for BlurRule {
|
||||
fn merge_with(&mut self, part: &Self) {
|
||||
merge_on_off!((self, part));
|
||||
|
||||
merge_clone_opt!((self, part), passes, radius, noise, ignore_alpha);
|
||||
merge_clone_opt!((self, part), passes, radius, noise, ignore_alpha, x_ray);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -266,11 +266,12 @@ impl MappedLayer {
|
||||
&& !target.should_block_out(self.rules.block_out_from))
|
||||
.then(|| {
|
||||
let fx_buffers = fx_buffers?;
|
||||
let fx_buffers = fx_buffers.borrow();
|
||||
|
||||
// TODO: respect sync point?
|
||||
let alpha_tex = gles_elems
|
||||
.and_then(|gles_elems| {
|
||||
let fx_buffers = fx_buffers.borrow();
|
||||
|
||||
let transform = fx_buffers.transform();
|
||||
|
||||
render_to_texture(
|
||||
@@ -301,11 +302,13 @@ impl MappedLayer {
|
||||
Some(
|
||||
self.blur
|
||||
.render(
|
||||
&fx_buffers,
|
||||
fx_buffers,
|
||||
blur_sample_area,
|
||||
self.rules.geometry_corner_radius.unwrap_or_default(),
|
||||
self.scale,
|
||||
geo,
|
||||
!self.rules.blur.x_ray.unwrap_or_default(),
|
||||
blur_sample_area.loc.to_f64(),
|
||||
)
|
||||
.map(Into::into),
|
||||
)
|
||||
|
||||
@@ -43,6 +43,7 @@ impl ResolvedLayerRules {
|
||||
radius: None,
|
||||
noise: None,
|
||||
ignore_alpha: None,
|
||||
x_ray: None,
|
||||
},
|
||||
shadow: ShadowRule {
|
||||
off: false,
|
||||
|
||||
@@ -1931,11 +1931,14 @@ impl<W: LayoutElement> Tile<W> {
|
||||
.and_then(|fx_buffers| {
|
||||
self.blur
|
||||
.render(
|
||||
&fx_buffers.borrow(),
|
||||
fx_buffers,
|
||||
blur_sample_area.to_i32_round(),
|
||||
radius,
|
||||
self.scale,
|
||||
animated_geo,
|
||||
self.focused_window().is_floating()
|
||||
&& !self.focused_window().rules().blur.x_ray.unwrap_or_default(),
|
||||
window_render_loc,
|
||||
)
|
||||
.map(Into::into)
|
||||
})
|
||||
|
||||
@@ -317,7 +317,6 @@ pub(super) unsafe fn get_main_buffer_blur(
|
||||
supports_instancing: bool,
|
||||
// dst is the region that we want blur on
|
||||
dst: Rectangle<i32, Physical>,
|
||||
is_tty: bool,
|
||||
alpha_tex: Option<&GlesTexture>,
|
||||
) -> Result<GlesTexture, GlesError> {
|
||||
let tex_size = fx_buffers
|
||||
@@ -335,6 +334,10 @@ pub(super) unsafe fn get_main_buffer_blur(
|
||||
dst
|
||||
};
|
||||
|
||||
// let dst_expanded = fx_buffers
|
||||
// .transform()
|
||||
// .transform_rect_in(dst_expanded, &tex_size);
|
||||
|
||||
let mut prev_fbo = 0;
|
||||
gl.GetIntegerv(ffi::FRAMEBUFFER_BINDING, &mut prev_fbo as *mut _);
|
||||
|
||||
@@ -374,52 +377,33 @@ pub(super) unsafe fn get_main_buffer_blur(
|
||||
// as the bound fbo size, so blitting uses dst immediately
|
||||
gl.BindFramebuffer(ffi::DRAW_FRAMEBUFFER, sample_fbo);
|
||||
|
||||
if is_tty {
|
||||
let src_x0 = dst_expanded.loc.x;
|
||||
let src_y0 = dst_expanded.loc.y;
|
||||
let src_x1 = dst_expanded.loc.x + dst_expanded.size.w;
|
||||
let src_y1 = dst_expanded.loc.y + dst_expanded.size.h;
|
||||
let dst_x0 = src_x0;
|
||||
let dst_y0 = src_y0;
|
||||
let dst_x1 = src_x1;
|
||||
let dst_y1 = src_y1;
|
||||
let dst_x0 = dst_expanded.loc.x;
|
||||
let dst_y0 = dst_expanded.loc.y;
|
||||
let dst_x1 = dst_expanded.loc.x + dst_expanded.size.w;
|
||||
let dst_y1 = dst_expanded.loc.y + dst_expanded.size.h;
|
||||
|
||||
gl.BlitFramebuffer(
|
||||
src_x0,
|
||||
src_y0,
|
||||
src_x1,
|
||||
src_y1,
|
||||
dst_x0,
|
||||
dst_y0,
|
||||
dst_x1,
|
||||
dst_y1,
|
||||
ffi::COLOR_BUFFER_BIT,
|
||||
ffi::LINEAR,
|
||||
);
|
||||
} else {
|
||||
let fb_height = tex_size.h;
|
||||
let src_expanded = fx_buffers
|
||||
.transform()
|
||||
.invert()
|
||||
.transform_rect_in(dst_expanded, &tex_size);
|
||||
|
||||
let dst_y0 = dst_expanded.loc.y + dst_expanded.size.h;
|
||||
let dst_y1 = dst_expanded.loc.y;
|
||||
let src_x0 = src_expanded.loc.x;
|
||||
let src_y0 = src_expanded.loc.y;
|
||||
let src_x1 = src_expanded.loc.x + src_expanded.size.w;
|
||||
let src_y1 = src_expanded.loc.y + src_expanded.size.h;
|
||||
|
||||
let src_x0 = dst_expanded.loc.x;
|
||||
let src_x1 = dst_expanded.loc.x + dst_expanded.size.w;
|
||||
let src_y0 = fb_height - dst_y0;
|
||||
let src_y1 = fb_height - dst_y1;
|
||||
|
||||
gl.BlitFramebuffer(
|
||||
src_x0,
|
||||
src_y0,
|
||||
src_x1,
|
||||
src_y1,
|
||||
src_x0,
|
||||
dst_y0,
|
||||
src_x1,
|
||||
dst_y1,
|
||||
ffi::COLOR_BUFFER_BIT,
|
||||
ffi::LINEAR,
|
||||
);
|
||||
}
|
||||
gl.BlitFramebuffer(
|
||||
src_x0,
|
||||
src_y0,
|
||||
src_x1,
|
||||
src_y1,
|
||||
dst_x0,
|
||||
dst_y0,
|
||||
dst_x1,
|
||||
dst_y1,
|
||||
ffi::COLOR_BUFFER_BIT,
|
||||
ffi::LINEAR,
|
||||
);
|
||||
|
||||
if gl.GetError() == ffi::INVALID_OPERATION {
|
||||
error!("TrueBlur needs GLES3.0 for blitting");
|
||||
|
||||
@@ -16,12 +16,24 @@ use smithay::backend::renderer::Texture;
|
||||
use smithay::utils::{Buffer, Logical, Physical, Point, Rectangle, Scale, Size, Transform};
|
||||
|
||||
use crate::backend::tty::{TtyFrame, TtyRenderer, TtyRendererError};
|
||||
use crate::render_helpers::blur::EffectsFramebufffersUserData;
|
||||
use crate::render_helpers::render_data::RendererData;
|
||||
use crate::render_helpers::renderer::AsGlesFrame;
|
||||
use crate::render_helpers::shaders::{mat3_uniform, Shaders};
|
||||
|
||||
use super::{CurrentBuffer, EffectsFramebuffers};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
enum BlurVariant {
|
||||
Optimized {
|
||||
texture: GlesTexture,
|
||||
},
|
||||
True {
|
||||
fx_buffers: EffectsFramebufffersUserData,
|
||||
config: niri_config::Blur,
|
||||
},
|
||||
}
|
||||
|
||||
/// Used for tracking commit counters of a collection of elements.
|
||||
#[derive(Clone, Default, Debug, PartialEq, Eq)]
|
||||
pub struct CommitTracker(HashMap<Id, CommitCounter>);
|
||||
@@ -97,27 +109,48 @@ impl Blur {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn render(
|
||||
&self,
|
||||
fx_buffers: &EffectsFramebuffers,
|
||||
fx_buffers: EffectsFramebufffersUserData,
|
||||
sample_area: Rectangle<i32, Logical>,
|
||||
corner_radius: CornerRadius,
|
||||
scale: f64,
|
||||
geometry: Rectangle<f64, Logical>,
|
||||
mut true_blur: bool,
|
||||
render_loc: Point<f64, Logical>,
|
||||
) -> Option<BlurRenderElement> {
|
||||
if !self.config.on {
|
||||
return None;
|
||||
}
|
||||
|
||||
// FIXME: true blur is broken on 90/270 transformed monitors
|
||||
if !matches!(
|
||||
fx_buffers.borrow().transform(),
|
||||
Transform::Normal | Transform::Flipped180,
|
||||
) {
|
||||
true_blur = false;
|
||||
}
|
||||
|
||||
let mut inner = self.inner.borrow_mut();
|
||||
|
||||
let Some(inner) = inner.as_mut() else {
|
||||
let elem = BlurRenderElement::new(
|
||||
fx_buffers,
|
||||
&fx_buffers.borrow(),
|
||||
sample_area,
|
||||
corner_radius,
|
||||
scale,
|
||||
self.config,
|
||||
geometry,
|
||||
self.alpha_tex.borrow().clone(),
|
||||
if true_blur {
|
||||
BlurVariant::True {
|
||||
fx_buffers: fx_buffers.clone(),
|
||||
config: self.config,
|
||||
}
|
||||
} else {
|
||||
BlurVariant::Optimized {
|
||||
texture: fx_buffers.borrow().optimized_blur.clone(),
|
||||
}
|
||||
},
|
||||
render_loc,
|
||||
);
|
||||
|
||||
*inner = Some(elem.clone());
|
||||
@@ -125,23 +158,48 @@ impl Blur {
|
||||
return Some(elem);
|
||||
};
|
||||
|
||||
if true_blur != matches!(&inner.variant, BlurVariant::True { .. }) {
|
||||
inner.variant = if true_blur {
|
||||
BlurVariant::True {
|
||||
fx_buffers: fx_buffers.clone(),
|
||||
config: self.config,
|
||||
}
|
||||
} else {
|
||||
BlurVariant::Optimized {
|
||||
texture: fx_buffers.borrow().optimized_blur.clone(),
|
||||
}
|
||||
};
|
||||
|
||||
inner.damage_all();
|
||||
}
|
||||
|
||||
let fx_buffers = fx_buffers.borrow();
|
||||
|
||||
if inner.sample_area == sample_area
|
||||
&& inner.geometry == geometry
|
||||
&& inner.scale == scale
|
||||
&& inner.corner_radius == corner_radius
|
||||
&& fx_buffers.output_size().w == inner.texture.size().w
|
||||
&& fx_buffers.output_size().h == inner.texture.size().h
|
||||
&& inner.render_loc == render_loc
|
||||
{
|
||||
if !matches!(&inner.variant, BlurVariant::Optimized { texture }
|
||||
if texture.size().w == fx_buffers.output_size().w
|
||||
&& texture.size().h == fx_buffers.output_size().h)
|
||||
{
|
||||
// If we are true blur, or if our output size changed, we need to re-render.
|
||||
// PERF: is there a better solution for true blur?
|
||||
inner.damage_all();
|
||||
}
|
||||
|
||||
return Some(inner.clone());
|
||||
}
|
||||
|
||||
inner.texture = fx_buffers.optimized_blur.clone();
|
||||
inner.render_loc = render_loc;
|
||||
inner.sample_area = sample_area;
|
||||
inner.alpha_tex = self.alpha_tex.borrow().clone();
|
||||
inner.scale = scale;
|
||||
inner.geometry = geometry;
|
||||
inner.damage_all();
|
||||
inner.update_uniforms(fx_buffers, &self.config);
|
||||
inner.update_uniforms(&fx_buffers, &self.config);
|
||||
|
||||
Some(inner.clone())
|
||||
}
|
||||
@@ -150,7 +208,6 @@ impl Blur {
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct BlurRenderElement {
|
||||
id: Id,
|
||||
texture: GlesTexture,
|
||||
uniforms: Vec<Uniform<'static>>,
|
||||
sample_area: Rectangle<i32, Logical>,
|
||||
alpha_tex: Option<GlesTexture>,
|
||||
@@ -158,6 +215,8 @@ pub struct BlurRenderElement {
|
||||
commit: CommitCounter,
|
||||
corner_radius: CornerRadius,
|
||||
geometry: Rectangle<f64, Logical>,
|
||||
variant: BlurVariant,
|
||||
render_loc: Point<f64, Logical>,
|
||||
}
|
||||
|
||||
impl BlurRenderElement {
|
||||
@@ -170,7 +229,7 @@ impl BlurRenderElement {
|
||||
/// - Display outdated/wrong contents
|
||||
/// - Not display anything since the buffer will be empty.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
fn new(
|
||||
fx_buffers: &EffectsFramebuffers,
|
||||
sample_area: Rectangle<i32, Logical>,
|
||||
corner_radius: CornerRadius,
|
||||
@@ -178,10 +237,11 @@ impl BlurRenderElement {
|
||||
config: niri_config::Blur,
|
||||
geometry: Rectangle<f64, Logical>,
|
||||
alpha_tex: Option<GlesTexture>,
|
||||
variant: BlurVariant,
|
||||
render_loc: Point<f64, Logical>,
|
||||
) -> Self {
|
||||
let mut this = Self {
|
||||
id: Id::new(),
|
||||
texture: fx_buffers.optimized_blur.clone(),
|
||||
uniforms: Vec::with_capacity(7),
|
||||
alpha_tex,
|
||||
sample_area,
|
||||
@@ -189,6 +249,8 @@ impl BlurRenderElement {
|
||||
corner_radius,
|
||||
geometry,
|
||||
commit: CommitCounter::default(),
|
||||
variant,
|
||||
render_loc,
|
||||
};
|
||||
|
||||
this.update_uniforms(fx_buffers, &config);
|
||||
@@ -270,7 +332,7 @@ impl Element for BlurRenderElement {
|
||||
}
|
||||
|
||||
fn opaque_regions(&self, scale: Scale<f64>) -> OpaqueRegions<i32, Physical> {
|
||||
if self.alpha_tex.is_some() {
|
||||
if self.alpha_tex.is_some() || matches!(&self.variant, BlurVariant::True { .. }) {
|
||||
return OpaqueRegions::default();
|
||||
}
|
||||
|
||||
@@ -296,7 +358,13 @@ impl Element for BlurRenderElement {
|
||||
}
|
||||
|
||||
fn geometry(&self, scale: Scale<f64>) -> Rectangle<i32, Physical> {
|
||||
self.sample_area.to_f64().to_physical_precise_round(scale)
|
||||
Rectangle::new(
|
||||
self.render_loc.to_physical_precise_round(scale),
|
||||
self.sample_area
|
||||
.to_f64()
|
||||
.to_physical_precise_round(scale)
|
||||
.size,
|
||||
)
|
||||
}
|
||||
|
||||
fn alpha(&self) -> f32 {
|
||||
@@ -308,97 +376,6 @@ impl Element for BlurRenderElement {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn draw_true_blur(
|
||||
fx_buffers: &mut EffectsFramebuffers,
|
||||
gles_frame: &mut GlesFrame,
|
||||
config: &niri_config::Blur,
|
||||
scale: f64,
|
||||
dst: Rectangle<i32, Physical>,
|
||||
corner_radius: f32,
|
||||
src: Rectangle<f64, Buffer>,
|
||||
damage: &[Rectangle<i32, Physical>],
|
||||
opaque_regions: &[Rectangle<i32, Physical>],
|
||||
alpha: f32,
|
||||
is_tty: bool,
|
||||
alpha_tex: Option<&GlesTexture>,
|
||||
) -> Result<(), GlesError> {
|
||||
fx_buffers.current_buffer = CurrentBuffer::Normal;
|
||||
|
||||
let shaders = Shaders::get_from_frame(gles_frame).blur.clone();
|
||||
let vbos = RendererData::get_from_frame(gles_frame).vbos;
|
||||
let supports_instancing = gles_frame
|
||||
.capabilities()
|
||||
.contains(&smithay::backend::renderer::gles::Capability::Instancing);
|
||||
let debug = !gles_frame.debug_flags().is_empty();
|
||||
let projection_matrix = glam::Mat3::from_cols_array(gles_frame.projection());
|
||||
|
||||
// Update the blur buffers.
|
||||
// We use gl ffi directly to circumvent some stuff done by smithay
|
||||
let blurred_texture = gles_frame.with_context(|gl| unsafe {
|
||||
super::get_main_buffer_blur(
|
||||
gl,
|
||||
&mut *fx_buffers,
|
||||
&shaders,
|
||||
*config,
|
||||
projection_matrix,
|
||||
scale as i32,
|
||||
&vbos,
|
||||
debug,
|
||||
supports_instancing,
|
||||
dst,
|
||||
is_tty,
|
||||
alpha_tex,
|
||||
)
|
||||
})??;
|
||||
|
||||
let program = Shaders::get_from_frame(gles_frame).blur_finish.clone();
|
||||
|
||||
let additional_uniforms = vec![
|
||||
Uniform::new(
|
||||
"geo",
|
||||
[
|
||||
dst.loc.x as f32,
|
||||
dst.loc.y as f32,
|
||||
dst.size.w as f32,
|
||||
dst.size.h as f32,
|
||||
],
|
||||
),
|
||||
Uniform::new("alpha", alpha),
|
||||
Uniform::new("noise", config.noise.0 as f32),
|
||||
Uniform::new("corner_radius", corner_radius),
|
||||
Uniform::new(
|
||||
"output_size",
|
||||
[
|
||||
fx_buffers.output_size.w as f32,
|
||||
fx_buffers.output_size.h as f32,
|
||||
],
|
||||
),
|
||||
Uniform::new(
|
||||
"ignore_alpha",
|
||||
if alpha_tex.is_some() {
|
||||
config.ignore_alpha.0 as f32
|
||||
} else {
|
||||
0.
|
||||
},
|
||||
),
|
||||
Uniform::new("alpha_tex", 1),
|
||||
];
|
||||
|
||||
gles_frame.render_texture_from_to(
|
||||
&blurred_texture,
|
||||
src,
|
||||
dst,
|
||||
damage,
|
||||
opaque_regions,
|
||||
Transform::Normal,
|
||||
alpha,
|
||||
program.as_ref(),
|
||||
&additional_uniforms,
|
||||
)
|
||||
}
|
||||
|
||||
impl RenderElement<GlesRenderer> for BlurRenderElement {
|
||||
fn draw(
|
||||
&self,
|
||||
@@ -432,17 +409,62 @@ impl RenderElement<GlesRenderer> for BlurRenderElement {
|
||||
})?;
|
||||
}
|
||||
|
||||
gles_frame.render_texture_from_to(
|
||||
&self.texture,
|
||||
src,
|
||||
downscaled_dst,
|
||||
damage,
|
||||
opaque_regions,
|
||||
Transform::Normal,
|
||||
1.0,
|
||||
Some(&program),
|
||||
&self.uniforms,
|
||||
)
|
||||
match &self.variant {
|
||||
BlurVariant::Optimized { texture } => gles_frame.render_texture_from_to(
|
||||
texture,
|
||||
src,
|
||||
downscaled_dst,
|
||||
damage,
|
||||
opaque_regions,
|
||||
Transform::Normal,
|
||||
1.,
|
||||
Some(&program),
|
||||
&self.uniforms,
|
||||
),
|
||||
BlurVariant::True { fx_buffers, config } => {
|
||||
let mut fx_buffers = fx_buffers.borrow_mut();
|
||||
|
||||
fx_buffers.current_buffer = CurrentBuffer::Normal;
|
||||
|
||||
let shaders = Shaders::get_from_frame(gles_frame).blur.clone();
|
||||
let vbos = RendererData::get_from_frame(gles_frame).vbos;
|
||||
let supports_instancing = gles_frame
|
||||
.capabilities()
|
||||
.contains(&smithay::backend::renderer::gles::Capability::Instancing);
|
||||
let debug = !gles_frame.debug_flags().is_empty();
|
||||
let projection_matrix = glam::Mat3::from_cols_array(gles_frame.projection());
|
||||
|
||||
// Update the blur buffers.
|
||||
// We use gl ffi directly to circumvent some stuff done by smithay
|
||||
let blurred_texture = gles_frame.with_context(|gl| unsafe {
|
||||
super::get_main_buffer_blur(
|
||||
gl,
|
||||
&mut fx_buffers,
|
||||
&shaders,
|
||||
*config,
|
||||
projection_matrix,
|
||||
self.scale as i32,
|
||||
&vbos,
|
||||
debug,
|
||||
supports_instancing,
|
||||
downscaled_dst,
|
||||
self.alpha_tex.as_ref(),
|
||||
)
|
||||
})??;
|
||||
|
||||
gles_frame.render_texture_from_to(
|
||||
&blurred_texture,
|
||||
src,
|
||||
downscaled_dst,
|
||||
damage,
|
||||
opaque_regions,
|
||||
fx_buffers.transform(),
|
||||
1.,
|
||||
Some(&program),
|
||||
&self.uniforms,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn underlying_storage(&self, _: &mut GlesRenderer) -> Option<UnderlyingStorage<'_>> {
|
||||
|
||||
Reference in New Issue
Block a user