Begin reworking camera items to accept external buffers and render requests

This commit is contained in:
UnderSampled
2023-09-03 14:19:43 -04:00
parent 5c8563f165
commit ff7b8273c8
2 changed files with 69 additions and 14 deletions

View File

@@ -260,8 +260,8 @@ fn main() {
let _span = debug_span!("StereoKit step"); let _span = debug_span!("StereoKit step");
let _span = _span.enter(); let _span = _span.enter();
camera::send_rendered();
hmd::frame(sk); hmd::frame(sk);
camera::update(sk);
#[cfg(feature = "wayland")] #[cfg(feature = "wayland")]
wayland.frame_event(sk); wayland.frame_event(sk);
destroy_queue::clear(); destroy_queue::clear();
@@ -298,6 +298,8 @@ fn main() {
audio::update(sk); audio::update(sk);
#[cfg(feature = "wayland")] #[cfg(feature = "wayland")]
wayland.make_context_current(); wayland.make_context_current();
camera::update(sk);
}, },
|_sk| { |_sk| {
info!("Cleanly shut down StereoKit"); info!("Cleanly shut down StereoKit");

View File

@@ -19,8 +19,10 @@ use mint::{RowMatrix4, Vector2};
use nanoid::nanoid; use nanoid::nanoid;
use once_cell::sync::OnceCell; use once_cell::sync::OnceCell;
use parking_lot::Mutex; use parking_lot::Mutex;
use rustc_hash::FxHashMap;
use serde::Deserialize; use serde::Deserialize;
use stardust_xr::{ use stardust_xr::{
scenegraph::ScenegraphError,
schemas::flex::{deserialize, serialize}, schemas::flex::{deserialize, serialize},
values::Transform, values::Transform,
}; };
@@ -28,6 +30,7 @@ use std::sync::Arc;
use stereokit::{ use stereokit::{
Color128, Material, Rect, RenderLayer, StereoKitDraw, Tex, TextureType, Transparency, Color128, Material, Rect, RenderLayer, StereoKitDraw, Tex, TextureType, Transparency,
}; };
use tokio::sync::{mpsc, oneshot};
lazy_static! { lazy_static! {
pub(super) static ref ITEM_TYPE_INFO_CAMERA: TypeInfo = TypeInfo { pub(super) static ref ITEM_TYPE_INFO_CAMERA: TypeInfo = TypeInfo {
@@ -49,13 +52,17 @@ struct FrameInfo {
pub struct CameraItem { pub struct CameraItem {
space: Arc<Spatial>, space: Arc<Spatial>,
frame_info: Mutex<FrameInfo>, frame_info: Mutex<FrameInfo>,
sk_tex: OnceCell<Tex>, sk_textures: Mutex<FxHashMap<(usize, usize), Tex>>,
sk_mat: OnceCell<Arc<Material>>, sk_mat: OnceCell<Arc<Material>>,
render_requests_tx: mpsc::Sender<(usize, oneshot::Sender<()>)>,
render_requests_rx: mpsc::Receiver<(usize, oneshot::Sender<()>)>,
rendered_notifiers: Mutex<Vec<oneshot::Sender<()>>>,
applied_to: Registry<ModelPart>, applied_to: Registry<ModelPart>,
apply_to: Registry<ModelPart>, apply_to: Registry<ModelPart>,
} }
impl CameraItem { impl CameraItem {
pub fn add_to(node: &Arc<Node>, proj_matrix: Mat4, px_size: Vector2<u32>) { pub fn add_to(node: &Arc<Node>, proj_matrix: Mat4, px_size: Vector2<u32>) {
let (render_requests_tx, render_requests_rx) = mpsc::channel(5);
Item::add_to( Item::add_to(
node, node,
nanoid!(), nanoid!(),
@@ -66,30 +73,47 @@ impl CameraItem {
proj_matrix, proj_matrix,
px_size, px_size,
}), }),
sk_tex: OnceCell::new(), sk_textures: Mutex::new(FxHashMap::default()),
sk_mat: OnceCell::new(), sk_mat: OnceCell::new(),
render_requests_tx,
render_requests_rx,
rendered_notifiers: Mutex::new(Vec::new()),
applied_to: Registry::new(), applied_to: Registry::new(),
apply_to: Registry::new(), apply_to: Registry::new(),
}), }),
); );
node.add_local_method("frame", CameraItem::frame_flex); node.add_local_method("render", CameraItem::render_flex);
node.add_local_signal( node.add_local_signal(
"apply_preview_material", "apply_preview_material",
CameraItem::apply_preview_material_flex, CameraItem::apply_preview_material_flex,
); );
} }
fn frame_flex( fn render_flex(
node: &Node, node: &Node,
_calling_client: Arc<Client>, _calling_client: Arc<Client>,
_message: Message, message: Message,
response: MethodResponseSender, response: MethodResponseSender,
) { ) {
response.wrap_sync(move || { let ItemType::Camera(camera) = &node.item.get().unwrap().specialization else {
let ItemType::Camera(_camera) = &node.item.get().unwrap().specialization else { let _ = response.send(Err(ScenegraphError::MethodError {
return Err(eyre!("Wrong item type?")) error: "Wrong item type?".to_string(),
}; }));
Ok(serialize(())?.into()) return;
};
let (rendered_tx, rendered_rx) = oneshot::channel();
let buffer_to_render: usize = deserialize(&message.data).unwrap();
tokio::task::spawn(async move {
camera
.render_requests_tx
.send((buffer_to_render, rendered_tx))
.await;
rendered_rx.await;
response.send(Ok(Vec::new().into()));
}); });
} }
@@ -101,11 +125,18 @@ impl CameraItem {
let ItemType::Camera(camera) = &node.item.get().unwrap().specialization else { let ItemType::Camera(camera) = &node.item.get().unwrap().specialization else {
bail!("Wrong item type?") bail!("Wrong item type?")
}; };
let model_part_node = let model_part_node =
calling_client.get_node("Model part", deserialize(&message.data).unwrap())?; calling_client.get_node("Model part", deserialize(&message.data).unwrap())?;
let Drawable::ModelPart(model_part) = model_part_node.get_aspect("Model part", "model part", |n| &n.drawable)? else {bail!("Drawable is not a model node")}; let Drawable::ModelPart(model_part) =
model_part_node.get_aspect("Model part", "model part", |n| &n.drawable)?
else {
bail!("Drawable is not a model node")
};
camera.applied_to.add_raw(model_part); camera.applied_to.add_raw(model_part);
camera.apply_to.add_raw(model_part); camera.apply_to.add_raw(model_part);
Ok(()) Ok(())
} }
@@ -135,7 +166,11 @@ impl CameraItem {
model_part.replace_material(sk_mat.clone()) model_part.replace_material(sk_mat.clone())
} }
if !self.applied_to.is_empty() { //if !self.applied_to.is_empty() {
//}
let mut render_notifiers = self.rendered_notifiers.lock();
while let Ok((buffer_to_render, rendered_tx)) = self.render_requests_rx.try_recv() {
sk.render_to( sk.render_to(
sk_tex, sk_tex,
frame_info.proj_matrix, frame_info.proj_matrix,
@@ -149,17 +184,35 @@ impl CameraItem {
h: 0.0, h: 0.0,
}, },
); );
render_notifiers.push(rendered_tx);
}
}
pub fn send_rendered(&self) {
for notifier in self.rendered_notifiers.lock().drain(..) {
notifier.send(());
} }
} }
} }
pub fn update(sk: &impl StereoKitDraw) { pub fn update(sk: &impl StereoKitDraw) {
for camera in ITEM_TYPE_INFO_CAMERA.items.get_valid_contents() { for camera in ITEM_TYPE_INFO_CAMERA.items.get_valid_contents() {
let ItemType::Camera(camera) = &camera.specialization else {continue}; let ItemType::Camera(camera) = &camera.specialization else {
continue;
};
camera.update(sk); camera.update(sk);
} }
} }
pub fn send_rendered() {
for camera in ITEM_TYPE_INFO_CAMERA.items.get_valid_contents() {
let ItemType::Camera(camera) = &camera.specialization else {
continue;
};
camera.send_rendered();
}
}
pub(super) fn create_camera_item_flex( pub(super) fn create_camera_item_flex(
_node: &Node, _node: &Node,
calling_client: Arc<Client>, calling_client: Arc<Client>,