bite-gpui 1.25.202

Zed's GPU-accelerated UI framework
Documentation
use std::{cell::Cell, fmt, rc::Rc, time::Duration};

use gpui::{
    BenchAppContext, Bounds, Context, InteractiveElement as _, IntoElement, ParentElement as _,
    Pixels, Render, SharedString, StatefulInteractiveElement as _, Styled as _, Window, div,
    prelude::FluentBuilder as _, px, rgb, size,
};

const COLUMN_COUNT: usize = 100;
const NODE_SIZE: f32 = 6.0;
const ROW_HEIGHT: f32 = 24.0;
const PANEL_WIDTH: f32 = 320.0;

#[derive(Default)]
struct RenderWork {
    rendered_frames: Cell<usize>,
    prepainted_children: Cell<usize>,
    invalid_children: Cell<usize>,
}

impl RenderWork {
    fn record_children(&self, bounds: &[Bounds<Pixels>], valid: impl Fn(&Bounds<Pixels>) -> bool) {
        self.prepainted_children
            .set(self.prepainted_children.get() + bounds.len());
        self.invalid_children.set(
            self.invalid_children.get() + bounds.iter().filter(|bounds| !valid(bounds)).count(),
        );
    }
}

struct ClosedInspectorInput {
    scale: usize,
    unit: &'static str,
    open_close_cycles: usize,
    other_window_inspected: bool,
}

impl fmt::Display for ClosedInspectorInput {
    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(
            formatter,
            "{}-{}-{}-cycles",
            self.scale, self.unit, self.open_close_cycles
        )?;
        if self.other_window_inspected {
            write!(formatter, "-other-window")?;
        }
        Ok(())
    }
}

fn closed_inspector_inputs(
    unit: &'static str,
    scales: impl IntoIterator<Item = usize>,
) -> Vec<ClosedInspectorInput> {
    let lifecycles = if cfg!(feature = "inspector") {
        vec![(0, false), (2, false), (0, true), (2, true)]
    } else {
        vec![(0, false)]
    };
    scales
        .into_iter()
        .flat_map(|scale| {
            lifecycles
                .iter()
                .map(
                    move |&(open_close_cycles, other_window_inspected)| ClosedInspectorInput {
                        scale,
                        unit,
                        open_close_cycles,
                        other_window_inspected,
                    },
                )
        })
        .collect()
}

#[gpui::bench(
    inputs = closed_inspector_inputs("nodes", [100, 1_000, 10_000]),
    input_name = "case",
    group = "closed_inspector_grid",
    fps = 120
)]
fn bare_grid(input: &ClosedInspectorInput, cx: &mut BenchAppContext) {
    assert_eq!(input.scale % COLUMN_COUNT, 0);
    measure_closed_inspector(
        input,
        cx,
        |work| BareGrid {
            node_count: input.scale,
            alternate: false,
            work,
        },
        |grid| grid.alternate = !grid.alternate,
    );
}

#[gpui::bench(
    inputs = closed_inspector_inputs("rows", [50, 500]),
    input_name = "case",
    group = "closed_inspector_panel",
    fps = 120
)]
fn panel(input: &ClosedInspectorInput, cx: &mut BenchAppContext) {
    measure_closed_inspector(
        input,
        cx,
        |work| Panel::new(input.scale, work),
        |panel| panel.selected_row = (panel.selected_row + 1) % panel.labels.len(),
    );
}

fn measure_closed_inspector<V: Render + 'static>(
    input: &ClosedInspectorInput,
    cx: &mut BenchAppContext,
    build_view: impl FnOnce(Rc<RenderWork>) -> V,
    mut update_view: impl FnMut(&mut V),
) {
    assert!(!cfg!(debug_assertions), "use --profile release-fast");
    let expected_children = input.scale;

    let work = Rc::new(RenderWork::default());
    let mut window = cx.add_empty_window();
    let view = window.update(|window, cx| {
        assert!(!window.is_inspector_picking(cx));
        window.replace_root(cx, |_, _| build_view(work.clone()))
    });
    cx.run_until_idle();
    for _ in 0..input.open_close_cycles {
        for open in [true, false] {
            window.update(|window, cx| {
                #[cfg(feature = "inspector")]
                window.toggle_inspector(cx);
                assert_eq!(window.is_inspector_picking(cx), open);
                window.refresh();
            });
            cx.run_until_idle();
        }
    }
    let mut other_window = input.other_window_inspected.then(|| {
        let mut window = cx.add_empty_window();
        window.update(|window, cx| {
            #[cfg(feature = "inspector")]
            window.toggle_inspector(cx);
            assert!(window.is_inspector_picking(cx));
        });
        window
    });
    cx.run_until_idle();
    let other_frames_before = other_window.as_mut().map(|window| {
        window.update(|window, _| {
            window
                .frame_duration_snapshot()
                .draw_duration_histogram
                .len()
        })
    });
    assert!(work.rendered_frames.get() > 0);
    assert_eq!(
        work.prepainted_children.get(),
        work.rendered_frames.get() * expected_children
    );
    assert_eq!(work.invalid_children.get(), 0);
    work.rendered_frames.set(0);
    work.prepainted_children.set(0);

    let frames_before = window.update(|window, _| window.frame_duration_snapshot());
    let mut updated_frames = 0;
    cx.bench_renderer(view, |view, _, cx| {
        update_view(view);
        updated_frames += 1;
        cx.notify();
    });
    let frames_after = window.update(|window, cx| {
        assert!(!window.is_inspector_picking(cx));
        window.frame_duration_snapshot()
    });

    let other_frames_after = other_window.as_mut().map(|window| {
        window.update(|window, cx| {
            assert!(window.is_inspector_picking(cx));
            window
                .frame_duration_snapshot()
                .draw_duration_histogram
                .len()
        })
    });
    assert_eq!(other_frames_after, other_frames_before);
    assert!(updated_frames > 0);
    assert_eq!(work.rendered_frames.get(), updated_frames);
    assert_eq!(
        work.prepainted_children.get(),
        updated_frames * expected_children
    );
    assert_eq!(work.invalid_children.get(), 0);
    assert_eq!(
        frames_after.draw_duration_histogram.len() - frames_before.draw_duration_histogram.len(),
        updated_frames as u64
    );
    assert_eq!(
        frames_after.dirty_to_present_histogram.len()
            - frames_before.dirty_to_present_histogram.len(),
        updated_frames as u64
    );
}

struct BareGrid {
    node_count: usize,
    alternate: bool,
    work: Rc<RenderWork>,
}

impl Render for BareGrid {
    fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
        self.work
            .rendered_frames
            .set(self.work.rendered_frames.get() + 1);
        let background = rgb(if self.alternate { 0x334455 } else { 0x445566 });

        div()
            .id("bare-grid")
            .flex()
            .flex_col()
            .size(px(COLUMN_COUNT as f32 * NODE_SIZE))
            .children((0..self.node_count / COLUMN_COUNT).map(|row_index| {
                let work = self.work.clone();
                div()
                    .on_children_prepainted(move |bounds, _, _| {
                        work.record_children(&bounds, |bounds| {
                            bounds.size == size(px(NODE_SIZE), px(NODE_SIZE))
                        });
                    })
                    .id(("row", row_index))
                    .flex()
                    .h(px(NODE_SIZE))
                    .flex_shrink_0()
                    .children((0..COLUMN_COUNT).map(|column_index| {
                        div()
                            .id(("node", column_index))
                            .size(px(NODE_SIZE))
                            .flex_shrink_0()
                            .bg(background)
                            .border_1()
                            .border_color(rgb(0x8899aa))
                            .rounded(px(2.0))
                            .when(column_index % 2 == 0, |element| element.cursor_pointer())
                    }))
            }))
    }
}

struct Panel {
    labels: Vec<SharedString>,
    counts: Vec<SharedString>,
    selected_row: usize,
    work: Rc<RenderWork>,
}

impl Panel {
    fn new(row_count: usize, work: Rc<RenderWork>) -> Self {
        Panel {
            labels: (0..row_count)
                .map(|index| {
                    SharedString::from(format!("crates/module_{}/src/file_{index}.rs", index % 17))
                })
                .collect(),
            counts: (0..row_count)
                .map(|index| SharedString::from(((index * 7) % 100).to_string()))
                .collect(),
            selected_row: 0,
            work,
        }
    }
}

impl Render for Panel {
    fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
        self.work
            .rendered_frames
            .set(self.work.rendered_frames.get() + 1);
        let work = self.work.clone();
        let selected_row = self.selected_row;

        div()
            .on_children_prepainted(move |bounds, _, _| {
                work.record_children(&bounds, |bounds| bounds.size.height == px(ROW_HEIGHT));
            })
            .id("panel")
            .flex()
            .flex_col()
            .w(px(PANEL_WIDTH))
            .h(px(ROW_HEIGHT * self.labels.len() as f32))
            .bg(rgb(0x1b1f24))
            .children(self.labels.iter().zip(&self.counts).enumerate().map(
                |(index, (label, count))| {
                    div()
                        .id(("row", index))
                        .flex()
                        .items_center()
                        .gap_2()
                        .px_2()
                        .h(px(ROW_HEIGHT))
                        .flex_shrink_0()
                        .rounded_sm()
                        .cursor_pointer()
                        .hover(|style| style.bg(rgb(0x2a3038)))
                        .active(|style| style.bg(rgb(0x343c46)))
                        .when(index == selected_row, |row| row.bg(rgb(0x1f4f82)))
                        .on_click(|_, _, _| {})
                        .child(
                            div()
                                .size_4()
                                .flex_shrink_0()
                                .rounded_sm()
                                .bg(rgb(if index % 3 == 0 { 0x6aa1ff } else { 0x8fbf6a })),
                        )
                        .child(
                            div()
                                .flex_1()
                                .overflow_hidden()
                                .text_sm()
                                .text_color(rgb(0xd0d4da))
                                .child(label.clone()),
                        )
                        .child(
                            div()
                                .text_xs()
                                .text_color(rgb(0x8a919c))
                                .child(count.clone()),
                        )
                },
            ))
    }
}

gpui::bench_group! {
    name = benches;
    config = criterion::Criterion::default()
        .sample_size(30)
        .warm_up_time(Duration::from_secs(1))
        .measurement_time(Duration::from_secs(5))
        .without_plots();
    targets = bare_grid, panel
}
gpui::bench_main!(benches);