refactor(camera item): pipe messageresponsesender through

This commit is contained in:
Nova
2023-09-18 03:15:52 -04:00
parent 1ee485f3c5
commit 6fc1bb2afa

View File

@@ -41,7 +41,7 @@ use stereokit::{
Color128, Material, Rect, RenderLayer, StereoKitDraw, Tex, TextureFormat, TextureType, Color128, Material, Rect, RenderLayer, StereoKitDraw, Tex, TextureFormat, TextureType,
Transparency, Transparency,
}; };
use tokio::sync::{mpsc, oneshot}; use tokio::sync::mpsc;
lazy_static! { lazy_static! {
pub(super) static ref ITEM_TYPE_INFO_CAMERA: TypeInfo = TypeInfo { pub(super) static ref ITEM_TYPE_INFO_CAMERA: TypeInfo = TypeInfo {
@@ -65,33 +65,34 @@ pub struct CameraItem {
frame_info: Mutex<FrameInfo>, frame_info: Mutex<FrameInfo>,
sk_tex: OnceCell<Tex>, sk_tex: OnceCell<Tex>,
sk_mat: OnceCell<Arc<Material>>, sk_mat: OnceCell<Arc<Material>>,
render_requests_tx: mpsc::Sender<(Dmabuf, oneshot::Sender<()>)>, render_requests_tx: mpsc::Sender<(Dmabuf, MethodResponseSender)>,
render_requests_rx: Mutex<mpsc::Receiver<(Dmabuf, oneshot::Sender<()>)>>, render_requests_rx: Mutex<mpsc::Receiver<(Dmabuf, MethodResponseSender)>>,
rendered_notifiers: Mutex<Vec<oneshot::Sender<()>>>, rendered_notifiers: Mutex<Vec<MethodResponseSender>>,
applied_to: Registry<ModelPart>, applied_preview_to: Registry<ModelPart>,
apply_to: Registry<ModelPart>, apply_preview_to: Registry<ModelPart>,
} }
impl CameraItem { impl CameraItem {
pub fn add_to(node: &Arc<Node>, proj_matrix: Mat4, preview_size: Vector2<u32>) { pub fn add_to(node: &Arc<Node>, proj_matrix: Mat4, preview_size: Vector2<u32>) {
let (render_requests_tx, render_requests_rx) = mpsc::channel(5); let (render_requests_tx, render_requests_rx) = mpsc::channel(5);
let camera_specialization = CameraItem {
space: node.spatial.get().unwrap().clone(),
frame_info: Mutex::new(FrameInfo {
proj_matrix,
preview_size,
}),
sk_tex: OnceCell::new(),
sk_mat: OnceCell::new(),
render_requests_tx,
render_requests_rx: Mutex::new(render_requests_rx),
rendered_notifiers: Mutex::new(Vec::new()),
applied_preview_to: Registry::new(),
apply_preview_to: Registry::new(),
};
Item::add_to( Item::add_to(
node, node,
nanoid!(), nanoid!(),
&ITEM_TYPE_INFO_CAMERA, &ITEM_TYPE_INFO_CAMERA,
ItemType::Camera(CameraItem { ItemType::Camera(camera_specialization),
space: node.spatial.get().unwrap().clone(),
frame_info: Mutex::new(FrameInfo {
proj_matrix,
preview_size,
}),
sk_tex: OnceCell::new(),
sk_mat: OnceCell::new(),
render_requests_tx,
render_requests_rx: Mutex::new(render_requests_rx),
rendered_notifiers: Mutex::new(Vec::new()),
applied_to: Registry::new(),
apply_to: Registry::new(),
}),
); );
node.add_local_method("render", CameraItem::render_flex); node.add_local_method("render", CameraItem::render_flex);
node.add_local_signal( node.add_local_signal(
@@ -106,15 +107,17 @@ impl CameraItem {
message: Message, message: Message,
response: MethodResponseSender, response: MethodResponseSender,
) { ) {
let ItemType::Camera(camera) = &node.item.get().unwrap().specialization else { let Some(item) = node.item.get() else {
let _ = response.send(Err(ScenegraphError::MethodError { error: "Item not found".to_string() }));
return
};
let ItemType::Camera(camera) = &item.specialization else {
let _ = response.send(Err(ScenegraphError::MethodError { let _ = response.send(Err(ScenegraphError::MethodError {
error: "Wrong item type?".to_string(), error: "Wrong item type?".to_string(),
})); }));
return; return
}; };
let (rendered_tx, rendered_rx) = oneshot::channel();
let buffer_info: BufferInfo = deserialize(&message.data).unwrap(); let buffer_info: BufferInfo = deserialize(&message.data).unwrap();
let mut fds = message.fds.iter(); let mut fds = message.fds.iter();
let mut builder = Dmabuf::builder( let mut builder = Dmabuf::builder(
@@ -138,11 +141,15 @@ impl CameraItem {
let _ = camera let _ = camera
.render_requests_tx .render_requests_tx
.try_send((buffer_to_render, rendered_tx)); .try_send((buffer_to_render, response));
tokio::task::spawn(async move { // tokio::task::spawn(async move {
let _ = rendered_rx.await; // let result = rendered_rx.await;
response.send(Ok(Vec::new().into())); // response.wrap_sync(|| {
}); // let result = result.map_err(|_| eyre!("failed to recieve response"))?;
// result.map_err(|e| eyre!(e))?;
// Ok(Message::from(Vec::new()))
// });
// });
} }
fn apply_preview_material_flex( fn apply_preview_material_flex(
@@ -162,8 +169,8 @@ impl CameraItem {
bail!("Drawable is not a model node") bail!("Drawable is not a model node")
}; };
camera.applied_to.add_raw(model_part); camera.applied_preview_to.add_raw(model_part);
camera.apply_to.add_raw(model_part); camera.apply_preview_to.add_raw(model_part);
Ok(()) Ok(())
} }
@@ -174,8 +181,12 @@ impl CameraItem {
pub fn update(&self, sk: &impl StereoKitDraw, buffer_manager: &mut BufferManager) { pub fn update(&self, sk: &impl StereoKitDraw, buffer_manager: &mut BufferManager) {
let frame_info = self.frame_info.lock(); let frame_info = self.frame_info.lock();
self.render_preview(sk, &*frame_info);
self.render_dmabuf(sk, buffer_manager, &*frame_info);
}
if !self.apply_to.is_empty() { fn render_preview(&self, sk: &impl StereoKitDraw, frame_info: &FrameInfo) {
if !self.apply_preview_to.is_empty() {
let sk_tex = self.sk_tex.get_or_init(|| { let sk_tex = self.sk_tex.get_or_init(|| {
sk.tex_gen_color( sk.tex_gen_color(
Color128::default(), Color128::default(),
@@ -192,12 +203,12 @@ impl CameraItem {
sk.material_set_transparency(&mat, Transparency::Blend); sk.material_set_transparency(&mat, Transparency::Blend);
Arc::new(mat) Arc::new(mat)
}); });
for model_part in self.apply_to.take_valid_contents() { for model_part in self.apply_preview_to.take_valid_contents() {
model_part.replace_material(sk_mat.clone()) model_part.replace_material(sk_mat.clone())
} }
} }
if !self.applied_to.is_empty() { if !self.applied_preview_to.is_empty() {
sk.render_to( sk.render_to(
self.sk_tex.get().unwrap(), self.sk_tex.get().unwrap(),
frame_info.proj_matrix, frame_info.proj_matrix,
@@ -212,17 +223,28 @@ impl CameraItem {
}, },
); );
} }
}
fn render_dmabuf(
&self,
sk: &impl StereoKitDraw,
buffer_manager: &mut BufferManager,
frame_info: &FrameInfo,
) {
let mut render_notifiers = self.rendered_notifiers.lock(); let mut render_notifiers = self.rendered_notifiers.lock();
let mut render_requests_rx = self.render_requests_rx.lock(); let mut render_requests_rx = self.render_requests_rx.lock();
while let Ok((buffer_to_render, rendered_tx)) = render_requests_rx.try_recv() { while let Ok((buffer_to_render, render_response_sender)) = render_requests_rx.try_recv() {
let Ok(smithay_tex) = buffer_manager let imported_dmabuf = buffer_manager
.renderer .renderer
.import_dmabuf(&buffer_to_render, None) .import_dmabuf(&buffer_to_render, None);
else { let smithay_tex = match imported_dmabuf {
// TODO: Failed to import the buffer somehow. This fails gracefully, but silently. Ok(t) => t,
render_notifiers.push(rendered_tx); Err(e) => {
continue; let _ = render_response_sender.send(Err(ScenegraphError::MethodError {
error: e.to_string(),
}));
continue;
}
}; };
let sk_tex = sk.tex_create(TextureType::IMAGE_NO_MIPS, TextureFormat::RGBA32); let sk_tex = sk.tex_create(TextureType::IMAGE_NO_MIPS, TextureFormat::RGBA32);
@@ -252,13 +274,13 @@ impl CameraItem {
h: 0.0, h: 0.0,
}, },
); );
render_notifiers.push(rendered_tx); render_notifiers.push(render_response_sender);
} }
} }
pub fn send_rendered(&self) { pub fn send_rendered(&self) {
for notifier in self.rendered_notifiers.lock().drain(..) { for notifier in self.rendered_notifiers.lock().drain(..) {
let _ = notifier.send(()); let _ = notifier.send(Ok(Vec::new().into()));
} }
} }
} }