|
@@ -28,6 +28,7 @@ pub trait WindowComponent: 'static + Sized + Component {
|
|
}
|
|
}
|
|
|
|
|
|
pub(crate) struct WindowState<WC: WindowComponent> {
|
|
pub(crate) struct WindowState<WC: WindowComponent> {
|
|
|
|
+ render_generation: usize,
|
|
wc: WC,
|
|
wc: WC,
|
|
root_node: LayoutNode,
|
|
root_node: LayoutNode,
|
|
window: Rc<winit::window::Window>,
|
|
window: Rc<winit::window::Window>,
|
|
@@ -56,13 +57,14 @@ impl<WC: WindowComponent> WindowState<WC> {
|
|
let layout = LinearAccess::new(&self.root_node, self.wc.root_widget().layout_node());
|
|
let layout = LinearAccess::new(&self.root_node, self.wc.root_widget().layout_node());
|
|
|
|
|
|
let mut bitmap = self.bitmap.borrow_mut();
|
|
let mut bitmap = self.bitmap.borrow_mut();
|
|
- if bitmap.as_ref().map(|v| v.size()) != Some(PixelSize::new(size.width as i32, size.height as i32)) {
|
|
|
|
|
|
+ if bitmap.as_ref().map(|v| v.size())
|
|
|
|
+ != Some(PixelSize::new(size.width as i32, size.height as i32))
|
|
|
|
+ {
|
|
bitmap.take();
|
|
bitmap.take();
|
|
}
|
|
}
|
|
|
|
|
|
- let bitmap = bitmap.get_or_insert_with(|| {
|
|
|
|
- kahlo::Bitmap::new(size.width as usize, size.height as usize)
|
|
|
|
- });
|
|
|
|
|
|
+ let bitmap = bitmap
|
|
|
|
+ .get_or_insert_with(|| kahlo::Bitmap::new(size.width as usize, size.height as usize));
|
|
|
|
|
|
let mut windowbuffer = kahlo::BitmapMut::<kahlo::formats::Bgr32>::new(
|
|
let mut windowbuffer = kahlo::BitmapMut::<kahlo::formats::Bgr32>::new(
|
|
unsafe {
|
|
unsafe {
|
|
@@ -74,14 +76,62 @@ impl<WC: WindowComponent> WindowState<WC> {
|
|
|
|
|
|
layout::recalculate(LayoutNodeAccess::new(&layout));
|
|
layout::recalculate(LayoutNodeAccess::new(&layout));
|
|
let before = std::time::Instant::now();
|
|
let before = std::time::Instant::now();
|
|
- self.wc.root_widget().render(uih.theme(), &mut bitmap.as_mut());
|
|
|
|
|
|
+
|
|
|
|
+ // save the layout tree for later dumping
|
|
|
|
+ let mut pre_render_dump = format!("render generation: {}\n", self.render_generation);
|
|
|
|
+ {
|
|
|
|
+ self.render_generation += 1;
|
|
|
|
+ crate::layout::dump_node_tree(LayoutNodeAccess::new(&layout), &mut pre_render_dump);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ self.wc
|
|
|
|
+ .root_widget()
|
|
|
|
+ .render(uih.theme(), &mut bitmap.as_mut());
|
|
windowbuffer.copy_from(
|
|
windowbuffer.copy_from(
|
|
bitmap,
|
|
bitmap,
|
|
PixelBox::from_size(bitmap.size()),
|
|
PixelBox::from_size(bitmap.size()),
|
|
- PixelPoint::zero()
|
|
|
|
|
|
+ PixelPoint::zero(),
|
|
);
|
|
);
|
|
let after = std::time::Instant::now();
|
|
let after = std::time::Instant::now();
|
|
- print!("render time: {:?} \r", (after - before));
|
|
|
|
|
|
+
|
|
|
|
+ // put the render time on the screen
|
|
|
|
+ // we're going to do this the very dumb way for now
|
|
|
|
+ let render_time = format!(
|
|
|
|
+ "time: {:.03}ms",
|
|
|
|
+ (after - before).as_micros() as f32 / 1000.0
|
|
|
|
+ );
|
|
|
|
+ let line = uih.theme().make_line(render_time.as_str()).render_line();
|
|
|
|
+
|
|
|
|
+ windowbuffer.fill_region_masked(
|
|
|
|
+ &line,
|
|
|
|
+ PixelBox::from_size(line.size()),
|
|
|
|
+ PixelPoint::new(
|
|
|
|
+ size.width as i32 - line.size().width,
|
|
|
|
+ size.height as i32 - line.size().height,
|
|
|
|
+ ),
|
|
|
|
+ uih.theme().foreground,
|
|
|
|
+ kahlo::colour::BlendMode::Simple,
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ // now put the pre-render layout dump on the window
|
|
|
|
+ // again, we're doing this the dumb way
|
|
|
|
+ let mut offset = 0;
|
|
|
|
+ for text in pre_render_dump.split("\n") {
|
|
|
|
+ if text.len() == 0 {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ let line = uih.theme().make_line(text).render_line();
|
|
|
|
+
|
|
|
|
+ windowbuffer.fill_region_masked(
|
|
|
|
+ &line,
|
|
|
|
+ PixelBox::from_size(line.size()),
|
|
|
|
+ PixelPoint::new(0, offset),
|
|
|
|
+ uih.theme().foreground,
|
|
|
|
+ kahlo::colour::BlendMode::Simple,
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ offset += line.height() as i32 + 1;
|
|
|
|
+ }
|
|
|
|
|
|
buf.present().unwrap();
|
|
buf.present().unwrap();
|
|
}
|
|
}
|
|
@@ -115,8 +165,16 @@ impl<WC: WindowComponent> WindowStateAccess for RefCell<WindowState<WC>> {
|
|
fn notify_resize(&self, new_size: PixelSize) {
|
|
fn notify_resize(&self, new_size: PixelSize) {
|
|
if Some(new_size) != self.borrow().bitmap.borrow().as_ref().map(|v| v.size()) {
|
|
if Some(new_size) != self.borrow().bitmap.borrow().as_ref().map(|v| v.size()) {
|
|
self.borrow_mut().bitmap.take();
|
|
self.borrow_mut().bitmap.take();
|
|
- self.borrow_mut().wc.root_widget().layout_node().relayout_tree();
|
|
|
|
- self.borrow_mut().wc.root_widget().layout_node().render_needed();
|
|
|
|
|
|
+ self.borrow_mut()
|
|
|
|
+ .wc
|
|
|
|
+ .root_widget()
|
|
|
|
+ .layout_node()
|
|
|
|
+ .relayout_tree();
|
|
|
|
+ self.borrow_mut()
|
|
|
|
+ .wc
|
|
|
|
+ .root_widget()
|
|
|
|
+ .layout_node()
|
|
|
|
+ .render_needed();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
fn push_event(&self, we: WindowEvent) {
|
|
fn push_event(&self, we: WindowEvent) {
|
|
@@ -160,6 +218,7 @@ impl<'r, 'l: 'r> WindowBuilder<'r, 'l> {
|
|
|
|
|
|
let wc = wc(self.ui_handle);
|
|
let wc = wc(self.ui_handle);
|
|
let wstate = Rc::new(RefCell::new(WindowState {
|
|
let wstate = Rc::new(RefCell::new(WindowState {
|
|
|
|
+ render_generation: 0,
|
|
wc,
|
|
wc,
|
|
root_node: LayoutNode::new(self.ui_handle.state.layout_cache.clone()),
|
|
root_node: LayoutNode::new(self.ui_handle.state.layout_cache.clone()),
|
|
window,
|
|
window,
|