aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/layout/focus_ring.rs54
-rw-r--r--src/layout/tile.rs2
-rw-r--r--src/render_helpers/border.rs59
-rw-r--r--src/render_helpers/resize.rs2
-rw-r--r--src/render_helpers/shader_element.rs46
5 files changed, 76 insertions, 87 deletions
diff --git a/src/layout/focus_ring.rs b/src/layout/focus_ring.rs
index 38e4a7ab..155d3254 100644
--- a/src/layout/focus_ring.rs
+++ b/src/layout/focus_ring.rs
@@ -17,7 +17,7 @@ pub struct FocusRing {
buffers: [SolidColorBuffer; 8],
locations: [Point<i32, Logical>; 8],
sizes: [Size<i32, Logical>; 8],
- borders: RefCell<Option<[BorderRenderElement; 8]>>,
+ borders: RefCell<[BorderRenderElement; 8]>,
full_size: Size<i32, Logical>,
is_active: bool,
is_border: bool,
@@ -183,38 +183,20 @@ impl FocusRing {
let shader = BorderRenderElement::shader(renderer);
let mut borders = self.borders.borrow_mut();
-
- // Initialize the border render elements.
- if let Some(shader) = shader {
- if let Some(borders) = &mut *borders {
- for elem in borders {
- elem.update_shader(shader);
- }
- } else {
- *borders = Some([(); 8].map(|()| BorderRenderElement::empty(shader.clone())));
- }
+ for elem in &mut *borders {
+ elem.update_shader(shader);
}
- let mut borders = if let Some(borders) = &mut *borders {
- let a = Some(borders.iter_mut().map(Some));
- let b = None;
- a.into_iter().flatten().chain(b.into_iter().flatten())
- } else {
- let a = None;
- let b = Some([None, None, None, None, None, None, None, None].into_iter());
- a.into_iter().flatten().chain(b.into_iter().flatten())
- };
-
let mut push = |buffer,
- border: Option<&mut BorderRenderElement>,
+ border: &mut BorderRenderElement,
location: Point<i32, Logical>,
size: Size<i32, Logical>| {
- let elem = if let Some(gradient) = gradient {
- let gradient_area = match gradient.relative_to {
- GradientRelativeTo::Window => full_rect,
- GradientRelativeTo::WorkspaceView => view_rect,
- };
- border.map(|border| {
+ let elem = if border.has_shader() {
+ if let Some(gradient) = gradient {
+ let gradient_area = match gradient.relative_to {
+ GradientRelativeTo::Window => full_rect,
+ GradientRelativeTo::WorkspaceView => view_rect,
+ };
border.update(
scale,
Rectangle::from_loc_and_size(location, size),
@@ -226,10 +208,8 @@ impl FocusRing {
border_width,
self.radius,
);
- border.clone().into()
- })
- } else if self.radius != CornerRadius::default() {
- border.map(|border| {
+ Some(border.clone().into())
+ } else if self.radius != CornerRadius::default() {
border.update(
scale,
Rectangle::from_loc_and_size(location, size),
@@ -241,8 +221,10 @@ impl FocusRing {
border_width,
self.radius,
);
- border.clone().into()
- })
+ Some(border.clone().into())
+ } else {
+ None
+ }
} else {
None
};
@@ -262,7 +244,7 @@ impl FocusRing {
if self.is_border {
for ((buf, border), (loc, size)) in zip(
- zip(&self.buffers, &mut borders),
+ zip(&self.buffers, &mut *borders),
zip(self.locations, self.sizes),
) {
push(buf, border, location + loc, size);
@@ -270,7 +252,7 @@ impl FocusRing {
} else {
push(
&self.buffers[0],
- borders.next().unwrap(),
+ &mut borders[0],
location + self.locations[0],
self.sizes[0],
);
diff --git a/src/layout/tile.rs b/src/layout/tile.rs
index a5ba6c6c..b47afc76 100644
--- a/src/layout/tile.rs
+++ b/src/layout/tile.rs
@@ -718,7 +718,7 @@ impl<W: LayoutElement> Tile<W> {
if radius != CornerRadius::default() {
if let Some(shader) = border_shader.clone() {
return BorderRenderElement::new(
- shader,
+ &shader,
scale,
elem.geometry(Scale::from(1.)).to_logical(1),
Rectangle::from_loc_and_size(Point::from((0, 0)), geo.size),
diff --git a/src/render_helpers/border.rs b/src/render_helpers/border.rs
index 3f2e69dd..6f2b7795 100644
--- a/src/render_helpers/border.rs
+++ b/src/render_helpers/border.rs
@@ -21,7 +21,6 @@ use crate::backend::tty::{TtyFrame, TtyRenderer, TtyRendererError};
#[derive(Debug, Clone)]
pub struct BorderRenderElement {
inner: ShaderRenderElement,
- shader: ShaderProgram,
params: Parameters,
}
@@ -41,7 +40,7 @@ struct Parameters {
impl BorderRenderElement {
#[allow(clippy::too_many_arguments)]
pub fn new(
- shader: ShaderProgram,
+ shader: &ShaderProgram,
scale: Scale<f64>,
area: Rectangle<i32, Logical>,
gradient_area: Rectangle<i32, Logical>,
@@ -52,19 +51,10 @@ impl BorderRenderElement {
border_width: f32,
corner_radius: CornerRadius,
) -> Self {
- let inner = ShaderRenderElement::new(
- shader.clone(),
- Default::default(),
- Default::default(),
- None,
- 1.,
- vec![],
- HashMap::new(),
- Kind::Unspecified,
- );
+ let mut inner = ShaderRenderElement::empty(Kind::Unspecified);
+ inner.update_shader(Some(shader));
let mut rv = Self {
inner,
- shader,
params: Parameters {
scale,
area,
@@ -81,20 +71,10 @@ impl BorderRenderElement {
rv
}
- pub fn empty(shader: ShaderProgram) -> Self {
- let inner = ShaderRenderElement::new(
- shader.clone(),
- Default::default(),
- Default::default(),
- None,
- 1.,
- vec![],
- HashMap::new(),
- Kind::Unspecified,
- );
+ pub fn empty() -> Self {
+ let inner = ShaderRenderElement::empty(Kind::Unspecified);
Self {
inner,
- shader,
params: Parameters {
scale: Scale::from(1.),
area: Default::default(),
@@ -109,23 +89,8 @@ impl BorderRenderElement {
}
}
- pub fn update_shader(&mut self, shader: &ShaderProgram) {
- if &self.shader == shader {
- return;
- }
-
- self.inner = ShaderRenderElement::new(
- shader.clone(),
- Default::default(),
- Default::default(),
- None,
- 1.,
- vec![],
- HashMap::new(),
- Kind::Unspecified,
- );
- self.update_inner();
- self.shader = shader.clone();
+ pub fn update_shader(&mut self, shader: Option<&ShaderProgram>) {
+ self.inner.update_shader(shader);
}
#[allow(clippy::too_many_arguments)]
@@ -222,11 +187,21 @@ impl BorderRenderElement {
);
}
+ pub fn has_shader(&self) -> bool {
+ self.inner.has_shader()
+ }
+
pub fn shader(renderer: &mut impl NiriRenderer) -> Option<&ShaderProgram> {
Shaders::get(renderer).border.as_ref()
}
}
+impl Default for BorderRenderElement {
+ fn default() -> Self {
+ Self::empty()
+ }
+}
+
impl Element for BorderRenderElement {
fn id(&self) -> &Id {
self.inner.id()
diff --git a/src/render_helpers/resize.rs b/src/render_helpers/resize.rs
index d01e4eb9..c728689a 100644
--- a/src/render_helpers/resize.rs
+++ b/src/render_helpers/resize.rs
@@ -92,7 +92,7 @@ impl ResizeRenderElement {
// Create the shader.
Self(ShaderRenderElement::new(
- shader,
+ Some(shader),
area,
size,
None,
diff --git a/src/render_helpers/shader_element.rs b/src/render_helpers/shader_element.rs
index 4e313fe3..75ed2780 100644
--- a/src/render_helpers/shader_element.rs
+++ b/src/render_helpers/shader_element.rs
@@ -19,8 +19,7 @@ use crate::backend::tty::{TtyFrame, TtyRenderer, TtyRendererError};
/// Renders a shader with optional texture input, on the primary GPU.
#[derive(Debug, Clone)]
pub struct ShaderRenderElement {
- shader: ShaderProgram,
- textures: HashMap<String, GlesTexture>,
+ shader: Option<ShaderProgram>,
id: Id,
commit_counter: CommitCounter,
area: Rectangle<i32, Logical>,
@@ -28,6 +27,7 @@ pub struct ShaderRenderElement {
opaque_regions: Vec<Rectangle<i32, Logical>>,
alpha: f32,
additional_uniforms: Vec<Uniform<'static>>,
+ textures: HashMap<String, GlesTexture>,
kind: Kind,
}
@@ -197,7 +197,7 @@ impl ShaderProgram {
impl ShaderRenderElement {
#[allow(clippy::too_many_arguments)]
pub fn new(
- shader: ShaderProgram,
+ shader: Option<ShaderProgram>,
area: Rectangle<i32, Logical>,
size: Size<f64, Buffer>,
opaque_regions: Option<Vec<Rectangle<i32, Logical>>>,
@@ -208,7 +208,6 @@ impl ShaderRenderElement {
) -> Self {
Self {
shader,
- textures,
id: Id::new(),
commit_counter: CommitCounter::default(),
area,
@@ -216,10 +215,35 @@ impl ShaderRenderElement {
opaque_regions: opaque_regions.unwrap_or_default(),
alpha,
additional_uniforms: uniforms.into_iter().map(|u| u.into_owned()).collect(),
+ textures,
+ kind,
+ }
+ }
+
+ pub fn empty(kind: Kind) -> Self {
+ Self {
+ shader: None,
+ id: Id::new(),
+ commit_counter: CommitCounter::default(),
+ area: Rectangle::default(),
+ size: Size::default(),
+ opaque_regions: vec![],
+ alpha: 1.,
+ additional_uniforms: vec![],
+ textures: HashMap::new(),
kind,
}
}
+ pub fn update_shader(&mut self, shader: Option<&ShaderProgram>) {
+ if self.shader.as_ref() == shader {
+ return;
+ }
+
+ self.shader = shader.cloned();
+ self.commit_counter.increment();
+ }
+
pub fn update(
&mut self,
area: Rectangle<i32, Logical>,
@@ -236,6 +260,10 @@ impl ShaderRenderElement {
self.commit_counter.increment();
}
+
+ pub fn has_shader(&self) -> bool {
+ self.shader.is_some()
+ }
}
impl Element for ShaderRenderElement {
@@ -281,6 +309,10 @@ impl RenderElement<GlesRenderer> for ShaderRenderElement {
) -> Result<(), GlesError> {
let frame = frame.as_gles_frame();
+ let Some(shader) = &self.shader else {
+ return Ok(());
+ };
+
let Some(resources) = Resources::get(frame) else {
return Ok(());
};
@@ -358,9 +390,9 @@ impl RenderElement<GlesRenderer> for ShaderRenderElement {
let has_tint = frame.debug_flags().contains(DebugFlags::TINT);
let program = if has_debug {
- &self.shader.0.debug
+ &shader.0.debug
} else {
- &self.shader.0.normal
+ &shader.0.normal
};
// render
@@ -406,7 +438,7 @@ impl RenderElement<GlesRenderer> for ShaderRenderElement {
let tint = if has_tint { 1.0f32 } else { 0.0f32 };
if has_debug {
- gl.Uniform1f(self.shader.0.uniform_tint, tint);
+ gl.Uniform1f(shader.0.uniform_tint, tint);
}
for uniform in &self.additional_uniforms {