layer.rs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. use async_recursion::async_recursion;
  2. use rand::{rngs::OsRng, Rng};
  3. use std::sync::{Arc, Weak};
  4. use crate::{
  5. gfx2::{DrawCall, DrawInstruction, Rectangle, RenderApiPtr},
  6. prop::{PropertyBool, PropertyPtr},
  7. scene::{Pimpl, SceneGraph, SceneGraphPtr2, SceneNodeId},
  8. };
  9. use super::{eval_rect, get_parent_rect, read_rect, DrawUpdate, OnModify, Stoppable};
  10. pub type RenderLayerPtr = Arc<RenderLayer>;
  11. pub struct RenderLayer {
  12. sg: SceneGraphPtr2,
  13. node_id: SceneNodeId,
  14. // Task is dropped at the end of the scope for RenderLayer, hence ending it
  15. #[allow(dead_code)]
  16. tasks: Vec<smol::Task<()>>,
  17. render_api: RenderApiPtr,
  18. dc_key: u64,
  19. is_visible: PropertyBool,
  20. rect: PropertyPtr,
  21. }
  22. impl RenderLayer {
  23. pub async fn new(
  24. ex: Arc<smol::Executor<'static>>,
  25. sg_ptr: SceneGraphPtr2,
  26. node_id: SceneNodeId,
  27. render_api: RenderApiPtr,
  28. ) -> Pimpl {
  29. let sg = sg_ptr.lock().await;
  30. let node = sg.get_node(node_id).unwrap();
  31. let node_name = node.name.clone();
  32. let is_visible =
  33. PropertyBool::wrap(node, "is_visible", 0).expect("RenderLayer::is_visible");
  34. let rect = node.get_property("rect").expect("RenderLayer::rect");
  35. drop(sg);
  36. let self_ = Arc::new_cyclic(|me: &Weak<Self>| {
  37. let mut on_modify = OnModify::new(ex.clone(), node_name, node_id, me.clone());
  38. on_modify.when_change(rect.clone(), Self::redraw);
  39. Self {
  40. sg: sg_ptr,
  41. node_id,
  42. tasks: on_modify.tasks,
  43. render_api,
  44. dc_key: OsRng.gen(),
  45. is_visible,
  46. rect,
  47. }
  48. });
  49. Pimpl::RenderLayer(self_)
  50. }
  51. async fn redraw(self: Arc<Self>) {
  52. let sg = self.sg.lock().await;
  53. let node = sg.get_node(self.node_id).unwrap();
  54. let Some(parent_rect) = get_parent_rect(&sg, node) else {
  55. return;
  56. };
  57. let Some(draw_update) = self.draw(&sg, &parent_rect) else {
  58. error!("RenderLayer {:?} failed to draw", node);
  59. return;
  60. };
  61. self.render_api.replace_draw_calls(draw_update.draw_calls).await;
  62. debug!("replace draw calls done");
  63. }
  64. pub fn draw(&self, sg: &SceneGraph, parent_rect: &Rectangle) -> Option<DrawUpdate> {
  65. debug!(target: "app", "RenderLayer::draw()");
  66. let node = sg.get_node(self.node_id).unwrap();
  67. if !self.is_visible.get() {
  68. debug!(target: "app", "invisible layer node '{}':{}", node.name, node.id);
  69. return None
  70. }
  71. if let Err(err) = eval_rect(self.rect.clone(), parent_rect) {
  72. panic!("Node {:?} bad rect property: {}", node, err);
  73. }
  74. let Ok(mut rect) = read_rect(self.rect.clone()) else {
  75. panic!("Node {:?} bad rect property", node);
  76. };
  77. rect.x += parent_rect.x;
  78. rect.y += parent_rect.x;
  79. if !parent_rect.includes(&rect) {
  80. error!(
  81. target: "app",
  82. "layer '{}':{} rect {:?} is not inside parent {:?}",
  83. node.name, node.id, rect, parent_rect
  84. );
  85. return None
  86. }
  87. debug!(target: "app", "Parent rect: {:?}", parent_rect);
  88. debug!(target: "app", "Viewport rect: {:?}", rect);
  89. // Apply viewport
  90. let mut draw_calls = vec![];
  91. let mut child_calls = vec![];
  92. for child_inf in node.get_children2() {
  93. let node = sg.get_node(child_inf.id).unwrap();
  94. let dcs = match &node.pimpl {
  95. Pimpl::RenderLayer(layer) => layer.draw(&sg, &rect),
  96. Pimpl::Mesh(mesh) => mesh.draw(&sg, &rect),
  97. _ => {
  98. error!(target: "app", "unhandled pimpl type");
  99. continue
  100. }
  101. };
  102. let Some(mut draw_update) = dcs else { continue };
  103. draw_calls.append(&mut draw_update.draw_calls);
  104. child_calls.push(draw_update.key);
  105. }
  106. let dc = DrawCall { instrs: vec![DrawInstruction::ApplyViewport(rect)], dcs: child_calls };
  107. draw_calls.push((self.dc_key, dc));
  108. Some(DrawUpdate { key: self.dc_key, draw_calls })
  109. }
  110. }
  111. impl Stoppable for RenderLayer {
  112. async fn stop(&self) {}
  113. }