use crate::{
App, ArenaClearNeeded, FocusId, PreparedRoots, Window, WindowMetrics, window::ElementArenaScope,
};
pub trait FramePipeline: 'static {
fn should_render(&mut self, is_dirty: bool, _metrics: &WindowMetrics) -> bool {
is_dirty
}
fn begin_frame(&mut self, window: &mut Window<'_>, cx: &mut App) {
window.begin_frame(cx);
}
fn evaluate_roots(&mut self, window: &mut Window<'_>, cx: &mut App) -> PreparedRoots {
window.evaluate_roots(cx)
}
fn layout_roots(&mut self, window: &mut Window<'_>, roots: &mut PreparedRoots, cx: &mut App) {
window.layout_roots(roots, cx);
}
fn paint_roots(&mut self, window: &mut Window<'_>, roots: PreparedRoots, cx: &mut App) {
window.paint_roots(roots, cx);
}
fn draw_roots(&mut self, window: &mut Window<'_>, cx: &mut App) {
let mut roots = self.evaluate_roots(window, cx);
self.layout_roots(window, &mut roots, cx);
self.paint_roots(window, roots, cx);
}
fn finish_frame(&mut self, window: &mut Window<'_>, cx: &mut App) {
window.finish_frame(cx);
}
fn complete_frame(&mut self, window: &mut Window<'_>, cx: &mut App) -> Option<FocusId> {
window.complete_frame(cx)
}
fn end_frame(
&mut self,
window: &mut Window<'_>,
cx: &mut App,
focus_before_listeners: Option<FocusId>,
) {
window.end_frame(cx, focus_before_listeners);
}
fn draw(&mut self, window: &mut Window<'_>, cx: &mut App) -> ArenaClearNeeded {
#[cfg(feature = "profiler")]
let frame_dirty = window.core.invalidator.take_frame_dirty();
#[cfg(feature = "profiler")]
window.core.window_profiler.begin_draw();
let arena_scope = ElementArenaScope::enter(&cx.element_arena);
self.begin_frame(window, cx);
window.restore_input_handler();
if !cx.mode.skip_drawing() {
self.draw_roots(window, cx);
#[cfg(feature = "profiler")]
{
let viewport_size = window.core.viewport_size;
let scale_factor = window.scale_factor();
window.core.debug_frame_overlay.paint(
&mut window.frame_state.next_frame.scene,
viewport_size,
scale_factor,
);
}
}
self.finish_frame(window, cx);
let focus_before_listeners = self.complete_frame(window, cx);
self.end_frame(window, cx, focus_before_listeners);
#[cfg(feature = "profiler")]
{
window
.core
.window_profiler
.set_refresh_interval(window.refresh_interval(cx));
let draw_duration = window
.core
.window_profiler
.end_draw(frame_dirty.dirty_at, frame_dirty.invalidations);
window.core.debug_frame_overlay.record_frame(draw_duration);
}
arena_scope.exit(&cx.element_arena)
}
}
pub struct StandardImmediatePipeline;
impl FramePipeline for StandardImmediatePipeline {}