feat: add nested Phase 0 compositor

This commit is contained in:
Samuel Onoja committed 2026-09-24 05:38:18 +01:00
1 parent aab447ef25
commit 475d433ec4
8 files changed
+2710 -2

No files matched your search

+106
View File
@@ -0,0 +1,106 @@
use std::{error::Error, time::Duration};
use smithay::{
backend::{
renderer::{
damage::OutputDamageTracker, element::surface::WaylandSurfaceRenderElement,
gles::GlesRenderer,
},
winit::{self, WinitEvent},
},
output::{Mode, Output, PhysicalProperties, Subpixel},
reexports::calloop::EventLoop,
utils::{Rectangle, Transform},
};
use crate::Ferese;
pub fn init(event_loop: &mut EventLoop<Ferese>, state: &mut Ferese) -> Result<(), Box<dyn Error>> {
let (mut backend, event_source) = winit::init()?;
let mode = Mode {
size: backend.window_size(),
refresh: 60_000,
};
let output = Output::new(
"ferese-winit".into(),
PhysicalProperties {
size: (0, 0).into(),
subpixel: Subpixel::Unknown,
make: "Ferese".into(),
model: "Nested".into(),
},
);
output.create_global::<Ferese>(&state.display_handle);
output.change_current_state(
Some(mode),
Some(Transform::Flipped180),
None,
Some((0, 0).into()),
);
output.set_preferred(mode);
state.space.map_output(&output, (0, 0));
let mut damage_tracker = OutputDamageTracker::from_output(&output);
event_loop
.handle()
.insert_source(event_source, move |event, _, state| match event {
WinitEvent::Resized { size, .. } => output.change_current_state(
Some(Mode {
size,
refresh: 60_000,
}),
None,
None,
None,
),
WinitEvent::Input(event) => state.process_input_event(event),
WinitEvent::Redraw => {
let damage = Rectangle::from_size(backend.window_size());
let rendered = (|| -> Result<(), Box<dyn Error>> {
{
let (renderer, mut framebuffer) = backend.bind()?;
smithay::desktop::space::render_output::<
_,
WaylandSurfaceRenderElement<GlesRenderer>,
_,
_,
>(
&output,
renderer,
&mut framebuffer,
1.0,
0,
[&state.space],
&[],
&mut damage_tracker,
[0.035, 0.04, 0.055, 1.0],
)?;
}
backend.submit(Some(&[damage]))?;
Ok(())
})();
if let Err(error) = rendered {
tracing::error!(%error, "nested renderer failed");
state.loop_signal.stop();
return;
}
state.space.elements().for_each(|window| {
window.send_frame(
&output,
state.start_time.elapsed(),
Some(Duration::ZERO),
|_, _| Some(output.clone()),
);
});
state.space.refresh();
state.popups.cleanup();
if let Err(error) = state.display_handle.flush_clients() {
tracing::debug!(%error, "failed to flush clients");
}
backend.window().request_redraw();
}
WinitEvent::CloseRequested => state.loop_signal.stop(),
_ => {}
})?;
Ok(())
}