aboutsummaryrefslogtreecommitdiff
path: root/src/window
diff options
context:
space:
mode:
Diffstat (limited to 'src/window')
-rw-r--r--src/window/mapped.rs111
1 files changed, 46 insertions, 65 deletions
diff --git a/src/window/mapped.rs b/src/window/mapped.rs
index 7210f8b0..58f733ba 100644
--- a/src/window/mapped.rs
+++ b/src/window/mapped.rs
@@ -3,7 +3,8 @@ use std::cmp::{max, min};
use niri_config::{BlockOutFrom, WindowRule};
use smithay::backend::renderer::element::solid::{SolidColorBuffer, SolidColorRenderElement};
-use smithay::backend::renderer::element::{Id, Kind};
+use smithay::backend::renderer::element::{AsRenderElements, Id, Kind};
+use smithay::backend::renderer::gles::GlesRenderer;
use smithay::desktop::space::SpaceElement as _;
use smithay::desktop::{PopupManager, Window};
use smithay::output::Output;
@@ -15,13 +16,11 @@ use smithay::wayland::compositor::{send_surface_state, with_states};
use smithay::wayland::shell::xdg::{SurfaceCachedState, ToplevelSurface};
use super::{ResolvedWindowRules, WindowRef};
-use crate::layout::{
- LayoutElement, LayoutElementRenderElement, LayoutElementSnapshotRenderElements,
-};
+use crate::layout::{LayoutElement, LayoutElementRenderElement, LayoutElementRenderSnapshot};
use crate::niri::WindowOffscreenId;
use crate::render_helpers::renderer::NiriRenderer;
-use crate::render_helpers::surface::render_and_save_from_surface_tree;
-use crate::render_helpers::{RenderSnapshot, RenderTarget};
+use crate::render_helpers::surface::render_snapshot_from_surface_tree;
+use crate::render_helpers::{BakedBuffer, RenderSnapshot, RenderTarget};
#[derive(Debug)]
pub struct Mapped {
@@ -43,7 +42,7 @@ pub struct Mapped {
block_out_buffer: RefCell<SolidColorBuffer>,
/// Snapshot of the last render for use in the close animation.
- last_render: RefCell<RenderSnapshot<LayoutElementSnapshotRenderElements>>,
+ last_render: RefCell<LayoutElementRenderSnapshot>,
}
impl Mapped {
@@ -95,6 +94,42 @@ impl Mapped {
self.is_focused = is_focused;
self.need_to_recompute_rules = true;
}
+
+ pub fn render_and_store_snapshot(&self, renderer: &mut GlesRenderer) {
+ let mut snapshot = self.last_render.borrow_mut();
+ if !snapshot.contents.is_empty() {
+ return;
+ }
+
+ snapshot.contents.clear();
+ snapshot.blocked_out_contents.clear();
+ snapshot.block_out_from = self.rules.block_out_from;
+
+ let mut buffer = self.block_out_buffer.borrow_mut();
+ buffer.resize(self.window.geometry().size);
+ snapshot.blocked_out_contents = vec![BakedBuffer {
+ buffer: buffer.clone(),
+ location: Point::from((0, 0)),
+ src: None,
+ dst: None,
+ }];
+
+ let buf_pos = self.window.geometry().loc.upscale(-1);
+
+ let surface = self.toplevel().wl_surface();
+ for (popup, popup_offset) in PopupManager::popups_for_surface(surface) {
+ let offset = self.window.geometry().loc + popup_offset - popup.geometry().loc;
+
+ render_snapshot_from_surface_tree(
+ renderer,
+ popup.wl_surface(),
+ buf_pos + offset,
+ &mut snapshot.contents,
+ );
+ }
+
+ render_snapshot_from_surface_tree(renderer, surface, buf_pos, &mut snapshot.contents);
+ }
}
impl LayoutElement for Mapped {
@@ -131,10 +166,9 @@ impl LayoutElement for Mapped {
Some(BlockOutFrom::ScreenCapture) => target != RenderTarget::Output,
};
- let mut buffer = self.block_out_buffer.borrow_mut();
- buffer.resize(self.window.geometry().size);
-
if block_out {
+ let mut buffer = self.block_out_buffer.borrow_mut();
+ buffer.resize(self.window.geometry().size);
let elem = SolidColorRenderElement::from_buffer(
&buffer,
location.to_physical_precise_round(scale),
@@ -146,64 +180,11 @@ impl LayoutElement for Mapped {
} else {
let buf_pos = location - self.window.geometry().loc;
let buf_pos = buf_pos.to_physical_precise_round(scale);
-
- let mut elements = vec![];
-
- // If we're rendering for output, save into last_render.
- let mut last_render = self.last_render.borrow_mut();
- // FIXME: when preview-render is active, last render contents will never update.
- let mut storage = if target == RenderTarget::Output {
- last_render.contents.clear();
- last_render.block_out_from = self.rules.block_out_from;
- last_render.blocked_out_contents = vec![SolidColorRenderElement::from_buffer(
- &buffer,
- (0, 0),
- scale,
- alpha,
- Kind::Unspecified,
- )
- .into()];
-
- Some(&mut last_render.contents)
- } else {
- None
- };
-
- let surface = self.toplevel().wl_surface();
- for (popup, popup_offset) in PopupManager::popups_for_surface(surface) {
- let offset = (self.window.geometry().loc + popup_offset - popup.geometry().loc)
- .to_physical_precise_round(scale);
-
- render_and_save_from_surface_tree(
- renderer,
- popup.wl_surface(),
- buf_pos,
- offset,
- scale,
- alpha,
- Kind::Unspecified,
- &mut elements,
- &mut storage,
- );
- }
-
- render_and_save_from_surface_tree(
- renderer,
- surface,
- buf_pos,
- Point::from((0., 0.)),
- scale,
- alpha,
- Kind::Unspecified,
- &mut elements,
- &mut storage,
- );
-
- elements
+ self.window.render_elements(renderer, buf_pos, scale, alpha)
}
}
- fn take_last_render(&self) -> RenderSnapshot<LayoutElementSnapshotRenderElements> {
+ fn take_last_render(&self) -> LayoutElementRenderSnapshot {
self.last_render.take()
}