feat(lapaloma-cartesian): picture cache pan-blit
- ChartCache + ChartCacheHandle (Arc<Mutex<...>>) cacheable entre frames. El Render host crea uno con chart_cache() y lo pasa al Element con .with_cache(handle). Sin handle, cada frame rebuild completo (correcto pero sin la optimización). - Hash estructural: plot rect + viewport.span (no x_min/y_min) + per-series (data.revision + data.len + stroke). 5 tests cubren estabilidad, pan no invalida, zoom invalida, data revision invalida, plot rect invalida. - En paint: si el hash matches, pan-blit = copia las coords cacheadas con offset (dx_px, dy_px) calculado del diff entre viewport.x_min cached vs actual. Salteamos LTTB + projection. - LineSeries::compute_projected expone el pipe LTTB + project_buffer como método público para que el Element pueda cachear sin pasar por paint(). - Demo multi-series usa el cache; header muestra "cache: N pan-blits / M rebuilds" en vivo para que se vea la métrica al draguear (pan-blits crece) y al zoomear (rebuilds crece). Limitación v0.1 anotada en código: el doc canónico (sección 4.4) usa una textura offscreen blitable; GPUI 0.2 no expone esa primitiva directa. La impl actual cachea coords proyectadas y emite las polilíneas con offset — mismo ahorro de CPU (saltea LTTB) sin GPU texture cache. 51 tests verdes (28 cartesian incluyendo 5 nuevos del structural_hash, 20 core, 3 render). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -14,7 +14,7 @@ use gpui::{
|
||||
MouseMoveEvent, MouseUpEvent, Point, Render, ScrollDelta, ScrollWheelEvent, Window,
|
||||
};
|
||||
|
||||
use lapaloma_cartesian::{ChartViewport, LapalomaChartElement};
|
||||
use lapaloma_cartesian::{chart_cache, ChartCacheHandle, ChartViewport, LapalomaChartElement};
|
||||
use lapaloma_core::buffer::DataBuffer;
|
||||
use lapaloma_render::{Color, StrokeStyle};
|
||||
use yahweh_launcher::launch_app;
|
||||
@@ -38,6 +38,7 @@ struct Demo {
|
||||
viewport: ChartViewport,
|
||||
initial_viewport: ChartViewport,
|
||||
drag: Option<DragAnchor>,
|
||||
chart_cache: ChartCacheHandle,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
@@ -65,6 +66,7 @@ impl Demo {
|
||||
viewport,
|
||||
initial_viewport: viewport,
|
||||
drag: None,
|
||||
chart_cache: chart_cache(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,6 +147,7 @@ impl Render for Demo {
|
||||
let plot_bg = Color::rgba(0.10, 0.12, 0.16, 1.0);
|
||||
let chart = LapalomaChartElement::new(self.viewport)
|
||||
.background(plot_bg)
|
||||
.with_cache(self.chart_cache.clone())
|
||||
.add_series_named(
|
||||
self.series_sin.clone(),
|
||||
StrokeStyle::new(2.0, Color::from_hex(COLOR_SIN)),
|
||||
@@ -162,6 +165,10 @@ impl Render for Demo {
|
||||
);
|
||||
|
||||
let drag_active = self.drag.is_some();
|
||||
let (pan_blits, rebuilds) = {
|
||||
let c = self.chart_cache.lock().unwrap();
|
||||
(c.pan_blits(), c.rebuilds())
|
||||
};
|
||||
|
||||
div()
|
||||
.id("lapaloma-demo-root")
|
||||
@@ -200,7 +207,12 @@ impl Render for Demo {
|
||||
.child(
|
||||
div()
|
||||
.text_color(theme.fg_muted)
|
||||
.child(if drag_active { "· dragging" } else { "" }),
|
||||
.child(format!(
|
||||
"· cache: {} pan-blits / {} rebuilds {}",
|
||||
pan_blits,
|
||||
rebuilds,
|
||||
if drag_active { "· dragging" } else { "" },
|
||||
)),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
|
||||
Reference in New Issue
Block a user