mirror of
https://github.com/marcoallegretti/WEFT_OS.git
synced 2026-03-27 01:13:09 +00:00
feat(compositor): implement surface compositing and layer shell rendering
Replace the clear-colour-only stub in render_output with full surface compositing via Space::render_elements_for_output. Changes: - drm_device.rs: add start_time: Instant to WeftDrmData for elapsed- time frame callbacks - drm.rs: rewrite render_output rendering block - collect SpaceRenderElements from Space via render_elements_for_output which includes both mapped windows and wlr-layer-shell surfaces from layer_map_for_output (sorted by z-index, clipped to output geometry) - pass collected elements to DrmOutput::render_frame - fix send_frame timing from Duration::ZERO to start_time.elapsed() with 16ms throttle hint - add space.refresh() and popups.cleanup() after each frame Use explicit inner block to scope space+drm borrows so post-render bookkeeping can access state mutably Cursor rendering deferred requires cursor theme loading or MemoryRenderBuffer setup; tracked separately.
This commit is contained in:
parent
732e572c43
commit
61bef1a0a7
2 changed files with 66 additions and 48 deletions
|
|
@ -5,7 +5,12 @@ pub fn run() -> anyhow::Result<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
use std::{collections::HashMap, path::Path, sync::Arc, time::Duration};
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
path::Path,
|
||||||
|
sync::Arc,
|
||||||
|
time::{Duration, Instant},
|
||||||
|
};
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
|
|
@ -71,6 +76,7 @@ const SUPPORTED_FORMATS: &[Fourcc] = &[
|
||||||
const SUPPORTED_FORMATS_8BIT_ONLY: &[Fourcc] = &[Fourcc::Abgr8888, Fourcc::Argb8888];
|
const SUPPORTED_FORMATS_8BIT_ONLY: &[Fourcc] = &[Fourcc::Abgr8888, Fourcc::Argb8888];
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
|
#[allow(dead_code)]
|
||||||
type WeftMultiRenderer<'a> = MultiRenderer<
|
type WeftMultiRenderer<'a> = MultiRenderer<
|
||||||
'a,
|
'a,
|
||||||
'a,
|
'a,
|
||||||
|
|
@ -239,6 +245,7 @@ pub fn run() -> anyhow::Result<()> {
|
||||||
devices: HashMap::new(),
|
devices: HashMap::new(),
|
||||||
keyboards: Vec::new(),
|
keyboards: Vec::new(),
|
||||||
display_handle,
|
display_handle,
|
||||||
|
start_time: Instant::now(),
|
||||||
});
|
});
|
||||||
|
|
||||||
let existing: Vec<(DrmNode, std::path::PathBuf)> = state
|
let existing: Vec<(DrmNode, std::path::PathBuf)> = state
|
||||||
|
|
@ -581,6 +588,13 @@ fn render_output(state: &mut WeftCompositorState, node: DrmNode, crtc: crtc::Han
|
||||||
.unwrap_or(d.primary_gpu)
|
.unwrap_or(d.primary_gpu)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let elapsed = state
|
||||||
|
.drm
|
||||||
|
.as_ref()
|
||||||
|
.map(|d| d.start_time.elapsed())
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
{
|
||||||
let WeftCompositorState {
|
let WeftCompositorState {
|
||||||
ref mut drm,
|
ref mut drm,
|
||||||
ref space,
|
ref space,
|
||||||
|
|
@ -615,12 +629,13 @@ fn render_output(state: &mut WeftCompositorState, node: DrmNode, crtc: crtc::Han
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Wave 2: clear-colour-only frame to establish the VBlank pipeline.
|
let elements = space
|
||||||
// Surface compositing is added in Wave 3.
|
.render_elements_for_output(&mut renderer, &output, 1.0)
|
||||||
let elements: &[WaylandSurfaceRenderElement<WeftMultiRenderer<'_>>] = &[];
|
.unwrap_or_default();
|
||||||
|
|
||||||
match surface.drm_output.render_frame(
|
match surface.drm_output.render_frame(
|
||||||
&mut renderer,
|
&mut renderer,
|
||||||
elements,
|
&elements,
|
||||||
[0.08_f32, 0.08, 0.08, 1.0],
|
[0.08_f32, 0.08, 0.08, 1.0],
|
||||||
FrameFlags::DEFAULT,
|
FrameFlags::DEFAULT,
|
||||||
) {
|
) {
|
||||||
|
|
@ -632,12 +647,14 @@ fn render_output(state: &mut WeftCompositorState, node: DrmNode, crtc: crtc::Han
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(e) => tracing::warn!(?e, "render_frame failed"),
|
Err(e) => tracing::warn!(?e, "render_frame failed"),
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
space.elements().for_each(|window| {
|
state.space.elements().for_each(|window| {
|
||||||
window.send_frame(&output, Duration::ZERO, Some(Duration::ZERO), |_, _| {
|
window.send_frame(&output, elapsed, Some(Duration::from_millis(16)), |_, _| {
|
||||||
Some(output.clone())
|
Some(output.clone())
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
state.space.refresh();
|
||||||
|
state.popups.cleanup();
|
||||||
let _ = state.display_handle.flush_clients();
|
let _ = state.display_handle.flush_clients();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use std::collections::HashMap;
|
use std::{collections::HashMap, time::Instant};
|
||||||
|
|
||||||
use smithay::{
|
use smithay::{
|
||||||
backend::{
|
backend::{
|
||||||
|
|
@ -55,4 +55,5 @@ pub struct WeftDrmData {
|
||||||
pub devices: HashMap<DrmNode, WeftDrmDevice>,
|
pub devices: HashMap<DrmNode, WeftDrmDevice>,
|
||||||
pub keyboards: Vec<smithay::reexports::input::Device>,
|
pub keyboards: Vec<smithay::reexports::input::Device>,
|
||||||
pub display_handle: DisplayHandle,
|
pub display_handle: DisplayHandle,
|
||||||
|
pub start_time: Instant,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue