diff --git a/Cargo.lock b/Cargo.lock index a9706b5ec553..dd3560e68acf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5121,7 +5121,7 @@ dependencies = [ "re_entity_db", "re_log", "re_log_types", - "re_query", + "re_query_cache", "re_renderer", "re_tracing", "re_types", @@ -5139,7 +5139,7 @@ dependencies = [ "re_data_store", "re_format", "re_log_types", - "re_query", + "re_query_cache", "re_renderer", "re_space_view", "re_tracing", diff --git a/crates/re_query_cache/src/lib.rs b/crates/re_query_cache/src/lib.rs index 4f57a78b83a6..2c6c69a9787d 100644 --- a/crates/re_query_cache/src/lib.rs +++ b/crates/re_query_cache/src/lib.rs @@ -12,6 +12,8 @@ pub use self::query::{ pub(crate) use self::cache::LatestAtCache; +pub use re_query::{QueryError, Result}; // convenience + // TODO(cmc): Supporting N>1 generically is quite painful due to limitations in declarative macros, // not that we care at the moment. seq_macro::seq!(NUM_COMP in 0..10 { paste::paste! { diff --git a/crates/re_space_view_text_log/Cargo.toml b/crates/re_space_view_text_log/Cargo.toml index 6c1369843dac..7f990c89b3be 100644 --- a/crates/re_space_view_text_log/Cargo.toml +++ b/crates/re_space_view_text_log/Cargo.toml @@ -21,7 +21,7 @@ re_data_ui.workspace = true re_entity_db.workspace = true re_log.workspace = true re_log_types.workspace = true -re_query.workspace = true +re_query_cache.workspace = true re_renderer.workspace = true re_tracing.workspace = true re_types.workspace = true diff --git a/crates/re_space_view_text_log/src/visualizer_system.rs b/crates/re_space_view_text_log/src/visualizer_system.rs index 7f0610a93b9a..a93847ca593d 100644 --- a/crates/re_space_view_text_log/src/visualizer_system.rs +++ b/crates/re_space_view_text_log/src/visualizer_system.rs @@ -1,7 +1,6 @@ use re_data_store::TimeRange; use re_entity_db::EntityPath; -use re_log_types::RowId; -use re_query::range_archetype; +use re_log_types::{RowId, TimeInt}; use re_types::{ archetypes::TextLog, components::{Color, Text, TextLogLevel}, @@ -66,28 +65,27 @@ impl VisualizerSystem for TextLogSystem { let timeline_query = re_data_store::RangeQuery::new(query.timeline, TimeRange::EVERYTHING); - let arch_views = range_archetype::( + re_query_cache::query_archetype_pov1_comp2::( + ctx.app_options.experimental_primary_caching_series, store, - &timeline_query, + &timeline_query.clone().into(), &data_result.entity_path, - ); - - for (time, arch_view) in arch_views { - let bodies = arch_view.iter_required_component::()?; - let levels = arch_view.iter_optional_component::()?; - let colors = arch_view.iter_optional_component::()?; - - for (body, level, color) in itertools::izip!(bodies, levels, colors) { - self.entries.push(Entry { - row_id: arch_view.primary_row_id(), - entity_path: data_result.entity_path.clone(), - time: time.map(|time| time.as_i64()), - color, - body, - level, - }); - } - } + |((time, row_id), _, bodies, levels, colors)| { + for (body, level, color) in + itertools::izip!(bodies.iter(), levels.iter(), colors.iter()) + { + self.entries.push(Entry { + row_id, + entity_path: data_result.entity_path.clone(), + // TODO(cmc): real support for timeless data in caches. + time: (time != TimeInt::MIN).then(|| time.as_i64()), + color: *color, + body: body.clone(), + level: level.clone(), + }); + } + }, + )?; } { diff --git a/crates/re_space_view_time_series/Cargo.toml b/crates/re_space_view_time_series/Cargo.toml index f6bd157df73e..703b7a44c591 100644 --- a/crates/re_space_view_time_series/Cargo.toml +++ b/crates/re_space_view_time_series/Cargo.toml @@ -19,7 +19,7 @@ all-features = true re_data_store.workspace = true re_format.workspace = true re_log_types.workspace = true -re_query.workspace = true +re_query_cache.workspace = true re_renderer.workspace = true re_space_view.workspace = true re_tracing.workspace = true diff --git a/crates/re_space_view_time_series/src/visualizer_system.rs b/crates/re_space_view_time_series/src/visualizer_system.rs index 39f5ffb4b273..52ccb72aa353 100644 --- a/crates/re_space_view_time_series/src/visualizer_system.rs +++ b/crates/re_space_view_time_series/src/visualizer_system.rs @@ -1,5 +1,5 @@ use re_data_store::TimeRange; -use re_query::{range_archetype, QueryError}; +use re_query_cache::QueryError; use re_types::{ archetypes::TimeSeriesScalar, components::{Color, Radius, Scalar, ScalarScattering, Text}, @@ -153,42 +153,48 @@ impl TimeSeriesSystem { let query = re_data_store::RangeQuery::new(query.timeline, TimeRange::new(from, to)); - let arch_views = range_archetype::< + re_query_cache::query_archetype_pov1_comp4::< TimeSeriesScalar, - { TimeSeriesScalar::NUM_COMPONENTS }, - >(store, &query, &data_result.entity_path); - - for (time, arch_view) in arch_views { - let Some(time) = time else { - continue; - }; // scalars cannot be timeless - - for (scalar, scattered, color, radius, label) in itertools::izip!( - arch_view.iter_required_component::()?, - arch_view.iter_optional_component::()?, - arch_view.iter_optional_component::()?, - arch_view.iter_optional_component::()?, - arch_view.iter_optional_component::()?, - ) { - let color = annotation_info.color(color.map(|c| c.to_array()), default_color); - let label = annotation_info.label(label.as_ref().map(|l| l.as_str())); - - const DEFAULT_RADIUS: f32 = 0.75; - - points.push(PlotPoint { - time: time.as_i64(), - value: scalar.0, - attrs: PlotPointAttrs { - label, - color, - radius: radius.map_or(DEFAULT_RADIUS, |r| r.0), - scattered: scattered.map_or(false, |s| s.0), - }, - }); - } - } - - points.sort_by_key(|s| s.time); + Scalar, + ScalarScattering, + Color, + Radius, + Text, + _, + >( + ctx.app_options.experimental_primary_caching_series, + store, + &query.clone().into(), + &data_result.entity_path, + |((time, _row_id), _, scalars, scatterings, colors, radii, labels)| { + re_tracing::profile_scope!("primary"); + + for (scalar, scattered, color, radius, label) in itertools::izip!( + scalars.iter(), + scatterings.iter(), + colors.iter(), + radii.iter(), + labels.iter() + ) { + let color = + annotation_info.color(color.map(|c| c.to_array()), default_color); + let label = annotation_info.label(label.as_ref().map(|l| l.as_str())); + + const DEFAULT_RADIUS: f32 = 0.75; + + points.push(PlotPoint { + time: time.as_i64(), + value: scalar.0, + attrs: PlotPointAttrs { + label, + color, + radius: radius.map_or(DEFAULT_RADIUS, |r| r.0), + scattered: scattered.map_or(false, |s| s.0), + }, + }); + } + }, + )?; if points.is_empty() { continue; diff --git a/crates/re_types/definitions/rerun/archetypes/text_log.fbs b/crates/re_types/definitions/rerun/archetypes/text_log.fbs index 4a3f02111ebc..3d9656e7894f 100644 --- a/crates/re_types/definitions/rerun/archetypes/text_log.fbs +++ b/crates/re_types/definitions/rerun/archetypes/text_log.fbs @@ -22,5 +22,5 @@ table TextLog ( level: rerun.components.TextLogLevel ("attr.rerun.component_recommended", nullable, order: 200); /// Optional color to use for the log line in the Rerun Viewer. - color: rerun.components.Color (nullable, order: 300); + color: rerun.components.Color ("attr.rerun.component_optional", nullable, order: 300); } diff --git a/crates/re_types/src/archetypes/text_log.rs b/crates/re_types/src/archetypes/text_log.rs index be703aa9bfc3..8c09d7c53de7 100644 --- a/crates/re_types/src/archetypes/text_log.rs +++ b/crates/re_types/src/archetypes/text_log.rs @@ -100,21 +100,27 @@ static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentName; 2usize]> = ] }); -static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentName; 1usize]> = - once_cell::sync::Lazy::new(|| ["rerun.components.InstanceKey".into()]); +static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentName; 2usize]> = + once_cell::sync::Lazy::new(|| { + [ + "rerun.components.Color".into(), + "rerun.components.InstanceKey".into(), + ] + }); -static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentName; 4usize]> = +static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentName; 5usize]> = once_cell::sync::Lazy::new(|| { [ "rerun.components.Text".into(), "rerun.components.TextLogIndicator".into(), "rerun.components.TextLogLevel".into(), + "rerun.components.Color".into(), "rerun.components.InstanceKey".into(), ] }); impl TextLog { - pub const NUM_COMPONENTS: usize = 4usize; + pub const NUM_COMPONENTS: usize = 5usize; } /// Indicator component for the [`TextLog`] [`::re_types_core::Archetype`] diff --git a/crates/re_viewer/src/ui/rerun_menu.rs b/crates/re_viewer/src/ui/rerun_menu.rs index fb939226b8f5..16b1989db180 100644 --- a/crates/re_viewer/src/ui/rerun_menu.rs +++ b/crates/re_viewer/src/ui/rerun_menu.rs @@ -299,6 +299,14 @@ fn experimental_feature_ui( ) .on_hover_text("Toggle primary caching for the 2D & 3D point cloud space views."); + re_ui + .checkbox( + ui, + &mut app_options.experimental_primary_caching_series, + "Primary caching: TextLogs & TimeSeries", + ) + .on_hover_text("Toggle primary caching for the time series & text logs space views."); + re_ui .checkbox( ui, diff --git a/crates/re_viewer_context/src/app_options.rs b/crates/re_viewer_context/src/app_options.rs index acc1b5d48644..feb5f7574097 100644 --- a/crates/re_viewer_context/src/app_options.rs +++ b/crates/re_viewer_context/src/app_options.rs @@ -28,6 +28,9 @@ pub struct AppOptions { /// Toggle primary caching for the 2D & 3D point cloud space views. pub experimental_primary_caching_point_clouds: bool, + /// Toggle primary caching for the time series & text logs space views. + pub experimental_primary_caching_series: bool, + /// Displays an overlay for debugging picking. pub show_picking_debug_overlay: bool, @@ -61,6 +64,10 @@ impl Default for AppOptions { // merged in. experimental_primary_caching_point_clouds: false, + // TODO(cmc): default to true for debug/rerun-workspace once minimal features have been + // merged in. + experimental_primary_caching_series: false, + show_picking_debug_overlay: false, show_blueprint_in_timeline: false, diff --git a/docs/content/reference/types/archetypes/text_log.md b/docs/content/reference/types/archetypes/text_log.md index 9c9af04ba07e..be884751fe2d 100644 --- a/docs/content/reference/types/archetypes/text_log.md +++ b/docs/content/reference/types/archetypes/text_log.md @@ -10,6 +10,8 @@ A log entry in a text log, comprised of a text body and its log level. **Recommended**: [`TextLogLevel`](../components/text_log_level.md) +**Optional**: [`Color`](../components/color.md) + ## Links * 🌊 [C++ API docs for `TextLog`](https://ref.rerun.io/docs/cpp/stable/structrerun_1_1archetypes_1_1TextLog.html) * 🐍 [Python API docs for `TextLog`](https://ref.rerun.io/docs/python/stable/common/archetypes#rerun.archetypes.TextLog)