perf(capture): add SceneLens GPU streams and retained scene reuse

Use persistent privacy-filtered capture targets and client-owned GPU buffers with fence completion, backpressure, negotiated frame rates and shared-memory fallback.

Invalidate output views on scene changes while preserving inactive-window callbacks and capture revocation. Include OBS memory-mask negotiation and native pixel, transport and recording regressions.
This commit is contained in:
Samuel Onoja committed 2026-10-24 19:58:54 +01:00
1 parent f49f62583d
commit 533cd74c94
40 files changed
+4704 -704

No files matched your search

+11
View File
@@ -191,6 +191,17 @@ impl Ferese {
return false;
}
// Mark before advancing so the final settling frame invalidates capture
// too, even if output_has_animations becomes false during this tick.
for output in self.space.outputs() {
if crate::backends::direct::capture::changes::tracked(output)
&& (self.output_has_animations(output)
|| self.output_has_pending_visual_changes(output))
{
crate::backends::direct::capture::changes::content_changed(output);
}
}
let delta = delta.mul_f64(self.animation_speed);
if let Some(workspace) = self
.focus_swipe()
+10 -2
View File
@@ -296,7 +296,12 @@ fn pixels(
output.clone(),
Rectangle::from_size((320, 240).into()),
));
let mut target = Some(texture.clone());
// Retain damage history as well as pixels: changing privacy policy
// must erase content already present in the reused capture target.
let mut target = std::mem::take(&mut state.nested_capture_texture);
target[0].get_or_insert_with(|| {
crate::backends::direct::capture::CaptureTarget::new(texture.clone(), output)
});
crate::backends::direct::capture::capture_output(
state,
renderer,
@@ -304,6 +309,7 @@ fn pixels(
output,
&scene,
);
state.nested_capture_texture = target;
let mut result = receiver.try_recv().unwrap().result.unwrap().pixels;
for pixel in result.chunks_exact_mut(4) {
pixel.swap(0, 2);
@@ -749,13 +755,15 @@ fn capture_privacy_pixels_and_policy_transitions() {
Rectangle::new((32, 24).into(), (160, 120).into()),
));
let scene = state.sample_frame(&output, Duration::ZERO);
let mut target = std::mem::take(&mut state.nested_capture_texture);
crate::backends::direct::capture::capture_output(
&mut state,
&mut renderer,
&mut Some(capture_texture.clone()),
&mut target,
&output,
&scene,
);
state.nested_capture_texture = target;
let region = receiver.try_recv().unwrap().result.unwrap();
assert_eq!((region.width, region.height), (160, 120));
assert!(
+1
View File
@@ -2,6 +2,7 @@ use super::{DesktopOutput, Ferese, Logical, Output, OutputId, Point};
impl Ferese {
pub(crate) fn defer_output_redraw(&mut self, output: Output) {
crate::backends::direct::capture::changes::content_changed(&output);
if !self.output_redraw_pending.contains(&output) {
self.output_redraw_pending.push(output);
}