Skip to content

Commit

Permalink
ViewerContext test harness 0.1 (#6432)
Browse files Browse the repository at this point in the history
### What

- Make the `render_context` field of `ViewerContext` an `Option` to make
it easier to crate a `ViewerContext` in a test environment.
- Introduce a (very basic) test helper that creates a `ViewerContext`
for use in unit test.
- Demo unit test that attempts to run `SelectionPanel::show_panel()`

Chained to #6431

There are many improvements that could be added:
- similar support for `ViewportBlueprint`
- make `re_log::warn/err` assert:
#6450
- add support for easily populating the stores with data
- benchmarking support?
- etc. etc.

### Checklist
* [x] I have read and agree to [Contributor
Guide](https://github.com/rerun-io/rerun/blob/main/CONTRIBUTING.md) and
the [Code of
Conduct](https://github.com/rerun-io/rerun/blob/main/CODE_OF_CONDUCT.md)
* [x] I've included a screenshot or gif (if applicable)
* [x] I have tested the web demo (if applicable):
* Using examples from latest `main` build:
[rerun.io/viewer](https://rerun.io/viewer/pr/6432?manifest_url=https://app.rerun.io/version/main/examples_manifest.json)
* Using full set of examples from `nightly` build:
[rerun.io/viewer](https://rerun.io/viewer/pr/6432?manifest_url=https://app.rerun.io/version/nightly/examples_manifest.json)
* [x] The PR title and labels are set such as to maximize their
usefulness for the next release's CHANGELOG
* [x] If applicable, add a new check to the [release
checklist](https://github.com/rerun-io/rerun/blob/main/tests/python/release_checklist)!

- [PR Build Summary](https://build.rerun.io/pr/6432)
- [Recent benchmark results](https://build.rerun.io/graphs/crates.html)
- [Wasm size tracking](https://build.rerun.io/graphs/sizes.html)

To run all checks from `main`, comment on the PR with `@rerun-bot
full-check`.
  • Loading branch information
abey79 authored May 28, 2024
1 parent b54e619 commit 68a1061
Show file tree
Hide file tree
Showing 29 changed files with 387 additions and 113 deletions.
14 changes: 9 additions & 5 deletions crates/re_data_ui/src/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,12 @@ pub fn tensor_ui(
None
};

let Some(render_ctx) = ctx.render_ctx else {
return;
};

let texture_result = gpu_bridge::tensor_to_gpu(
ctx.render_ctx,
render_ctx,
&debug_name,
tensor_data_row_id,
tensor,
Expand All @@ -147,7 +151,7 @@ pub fn tensor_ui(
ui.set_min_size(preview_size);

show_image_preview(
ctx.render_ctx,
render_ctx,
ctx.re_ui,
ui,
texture.clone(),
Expand All @@ -158,7 +162,7 @@ pub fn tensor_ui(
// Show larger image on hover.
let preview_size = Vec2::splat(400.0);
show_image_preview(
ctx.render_ctx,
render_ctx,
ctx.re_ui,
ui,
texture.clone(),
Expand Down Expand Up @@ -216,7 +220,7 @@ pub fn tensor_ui(
.min(texture_size(texture))
.min(egui::vec2(150.0, 300.0));
let response = show_image_preview(
ctx.render_ctx,
render_ctx,
ctx.re_ui,
ui,
texture.clone(),
Expand All @@ -227,7 +231,7 @@ pub fn tensor_ui(
if let Some(pointer_pos) = ui.ctx().pointer_latest_pos() {
let image_rect = response.rect;
show_zoomed_image_region_tooltip(
ctx.render_ctx,
render_ctx,
ui,
response,
tensor_data_row_id,
Expand Down
33 changes: 33 additions & 0 deletions crates/re_selection_panel/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,36 @@ mod space_view_entity_picker;
mod space_view_space_origin_ui;

pub use selection_panel::SelectionPanel;

#[cfg(test)]
mod test {
use super::*;
use re_data_store::LatestAtQuery;
use re_viewer_context::{blueprint_timeline, Item, SpaceViewId};
use re_viewport_blueprint::ViewportBlueprint;

/// This test mainly serve to demonstrate that non-trivial UI code can be executed with a "fake"
/// [`ViewerContext`].
// TODO(#6450): check that no warning/error is logged
#[test]
fn test_selection_panel() {
re_log::setup_logging();

let mut test_ctx = re_viewer_context::test_context::TestContext::default();
test_ctx.edit_selection(|selection_state| {
selection_state.set_selection(Item::SpaceView(SpaceViewId::random()));
});

test_ctx.run(|ctx, ui| {
let (sender, _) = std::sync::mpsc::channel();
let blueprint = ViewportBlueprint::try_from_db(
ctx.store_context.blueprint,
&LatestAtQuery::latest(blueprint_timeline()),
sender,
);

let mut selection_panel = SelectionPanel::default();
selection_panel.show_panel(ctx, &blueprint, &mut Default::default(), ui, true);
});
}
}
7 changes: 4 additions & 3 deletions crates/re_space_view_spatial/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ mod ui_2d;
mod ui_3d;
mod visualizers;

use re_renderer::RenderContext;
use re_types::blueprint::components::BackgroundKind;
use re_types::components::{Resolution, TensorData};

Expand Down Expand Up @@ -78,7 +79,7 @@ fn query_pinhole(
}

pub(crate) fn configure_background(
ctx: &re_viewer_context::ViewerContext<'_>,
render_ctx: &RenderContext,
kind: BackgroundKind,
color: re_types::components::Color,
) -> (Option<re_renderer::QueueableDrawData>, re_renderer::Rgba) {
Expand All @@ -88,7 +89,7 @@ pub(crate) fn configure_background(
BackgroundKind::GradientDark => (
Some(
renderer::GenericSkyboxDrawData::new(
ctx.render_ctx,
render_ctx,
renderer::GenericSkyboxType::GradientDark,
)
.into(),
Expand All @@ -99,7 +100,7 @@ pub(crate) fn configure_background(
BackgroundKind::GradientBright => (
Some(
renderer::GenericSkyboxDrawData::new(
ctx.render_ctx,
render_ctx,
renderer::GenericSkyboxType::GradientBright,
)
.into(),
Expand Down
34 changes: 20 additions & 14 deletions crates/re_space_view_spatial/src/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,10 @@ pub fn picking(
return Ok(response);
};

let Some(render_ctx) = ctx.render_ctx else {
return Err(SpaceViewSystemExecutionError::NoRenderContextError);
};

let picking_context = PickingContext::new(
pointer_pos_ui,
space_from_ui,
Expand All @@ -453,7 +457,7 @@ pub fn picking(
.at_most(128.0) as u32;

let _ = view_builder.schedule_picking_rect(
ctx.render_ctx,
render_ctx,
re_renderer::RectInt::from_middle_and_extent(
picking_context.pointer_in_pixel.as_ivec2(),
glam::uvec2(picking_rect_size, picking_rect_size),
Expand All @@ -467,7 +471,7 @@ pub fn picking(
let images = visualizers.get::<ImageVisualizer>()?;

let picking_result = picking_context.pick(
ctx.render_ctx,
render_ctx,
query.space_view_id.gpu_readback_id(),
&state.previous_picking_result,
&images.images,
Expand Down Expand Up @@ -725,18 +729,20 @@ fn image_hover_ui(
let tensor_stats = ctx.cache.entry(|c: &mut TensorStatsCache| {
c.entry(tensor_data_row_id, &decoded_tensor)
});
show_zoomed_image_region(
ctx.render_ctx,
ui,
tensor_data_row_id,
&decoded_tensor,
&tensor_stats,
&annotations,
meaning,
meter,
&tensor_name,
[coords[0] as _, coords[1] as _],
);
if let Some(render_ctx) = ctx.render_ctx {
show_zoomed_image_region(
render_ctx,
ui,
tensor_data_row_id,
&decoded_tensor,
&tensor_stats,
&annotations,
meaning,
meter,
&tensor_name,
[coords[0] as _, coords[1] as _],
);
}
}
Err(err) => re_log::warn_once!(
"Encountered problem decoding tensor at path {tensor_name}: {err}"
Expand Down
12 changes: 8 additions & 4 deletions crates/re_space_view_spatial/src/ui_2d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,8 +246,6 @@ pub fn view_2d(
return Ok(());
};

let mut view_builder = ViewBuilder::new(ctx.render_ctx, target_config);

// Create labels now since their shapes participate are added to scene.ui for picking.
let (label_shapes, ui_rects) = create_labels(
collect_ui_labels(&parts),
Expand All @@ -258,6 +256,12 @@ pub fn view_2d(
SpatialSpaceViewKind::TwoD,
);

let Some(render_ctx) = ctx.render_ctx else {
return Err(SpaceViewSystemExecutionError::NoRenderContextError);
};

let mut view_builder = ViewBuilder::new(render_ctx, target_config);

if ui.ctx().dragged_id().is_none() {
response = picking(
ctx,
Expand All @@ -283,7 +287,7 @@ pub fn view_2d(
let background = re_viewport_blueprint::view_property::<Background>(ctx, query.space_view_id)
.unwrap_or(Background::DEFAULT_2D);
let (background_drawable, clear_color) = crate::configure_background(
ctx,
render_ctx,
background.kind,
background.color.unwrap_or(Background::DEFAULT_COLOR_2D),
);
Expand All @@ -295,7 +299,7 @@ pub fn view_2d(

if let Some(mode) = screenshot_context_menu(ctx, &response) {
view_builder
.schedule_screenshot(ctx.render_ctx, query.space_view_id.gpu_readback_id(), mode)
.schedule_screenshot(render_ctx, query.space_view_id.gpu_readback_id(), mode)
.ok();
}

Expand Down
58 changes: 31 additions & 27 deletions crates/re_space_view_spatial/src/ui_3d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -466,30 +466,6 @@ pub fn view_3d(
);
let eye = view_eye.to_eye();

// Various ui interactions draw additional lines.
let mut line_builder = LineDrawableBuilder::new(ctx.render_ctx);
line_builder.radius_boost_in_ui_points_for_outlines(SIZE_BOOST_IN_POINTS_FOR_LINE_OUTLINES);
// We don't know ahead of time how many lines we need, but it's not gonna be a huge amount!
line_builder.reserve_strips(32)?;
line_builder.reserve_vertices(64)?;

// Origin gizmo if requested.
// TODO(andreas): Move this to the transform3d_arrow scene part.
// As of #2522 state is now longer accessible there, move the property to a context?
if state.state_3d.show_axes {
let axis_length = 1.0; // The axes are also a measuring stick
crate::visualizers::add_axis_arrows(
&mut line_builder,
macaw::Affine3A::IDENTITY,
None,
axis_length,
re_renderer::OutlineMaskPreference::NONE,
);

// If we are showing the axes for the space, then add the space origin to the bounding box.
state.bounding_boxes.current.extend(glam::Vec3::ZERO);
}

// Determine view port resolution and position.
let resolution_in_pixel =
gpu_bridge::viewport_resolution_in_pixels(rect, ui.ctx().pixels_per_point());
Expand Down Expand Up @@ -519,7 +495,35 @@ pub fn view_3d(
.then(|| outline_config(ui.ctx())),
};

let mut view_builder = ViewBuilder::new(ctx.render_ctx, target_config);
let Some(render_ctx) = ctx.render_ctx else {
return Err(SpaceViewSystemExecutionError::NoRenderContextError);
};

// Various ui interactions draw additional lines.
let mut line_builder = LineDrawableBuilder::new(render_ctx);
line_builder.radius_boost_in_ui_points_for_outlines(SIZE_BOOST_IN_POINTS_FOR_LINE_OUTLINES);
// We don't know ahead of time how many lines we need, but it's not gonna be a huge amount!
line_builder.reserve_strips(32)?;
line_builder.reserve_vertices(64)?;

// Origin gizmo if requested.
// TODO(andreas): Move this to the transform3d_arrow scene part.
// As of #2522 state is now longer accessible there, move the property to a context?
if state.state_3d.show_axes {
let axis_length = 1.0; // The axes are also a measuring stick
crate::visualizers::add_axis_arrows(
&mut line_builder,
macaw::Affine3A::IDENTITY,
None,
axis_length,
re_renderer::OutlineMaskPreference::NONE,
);

// If we are showing the axes for the space, then add the space origin to the bounding box.
state.bounding_boxes.current.extend(glam::Vec3::ZERO);
}

let mut view_builder = ViewBuilder::new(render_ctx, target_config);

// Create labels now since their shapes participate are added to scene.ui for picking.
let (label_shapes, ui_rects) = create_labels(
Expand Down Expand Up @@ -610,7 +614,7 @@ pub fn view_3d(
// Screenshot context menu.
if let Some(mode) = screenshot_context_menu(ctx, &response) {
view_builder
.schedule_screenshot(ctx.render_ctx, query.space_view_id.gpu_readback_id(), mode)
.schedule_screenshot(render_ctx, query.space_view_id.gpu_readback_id(), mode)
.ok();
}

Expand Down Expand Up @@ -668,7 +672,7 @@ pub fn view_3d(
let background = re_viewport_blueprint::view_property::<Background>(ctx, query.space_view_id)
.unwrap_or(Background::DEFAULT_3D);
let (background_drawable, clear_color) = crate::configure_background(
ctx,
render_ctx,
background.kind,
background.color.unwrap_or(Background::DEFAULT_COLOR_3D),
);
Expand Down
6 changes: 5 additions & 1 deletion crates/re_space_view_spatial/src/visualizers/arrows2d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,11 @@ impl VisualizerSystem for Arrows2DVisualizer {
view_query: &ViewQuery<'_>,
view_ctx: &ViewContextCollection,
) -> Result<Vec<re_renderer::QueueableDrawData>, SpaceViewSystemExecutionError> {
let mut line_builder = LineDrawableBuilder::new(ctx.render_ctx);
let Some(render_ctx) = ctx.render_ctx else {
return Err(SpaceViewSystemExecutionError::NoRenderContextError);
};

let mut line_builder = LineDrawableBuilder::new(render_ctx);
line_builder.radius_boost_in_ui_points_for_outlines(SIZE_BOOST_IN_POINTS_FOR_LINE_OUTLINES);

super::entity_iterator::process_archetype::<Self, Arrows2D, _>(
Expand Down
6 changes: 5 additions & 1 deletion crates/re_space_view_spatial/src/visualizers/arrows3d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,11 @@ impl VisualizerSystem for Arrows3DVisualizer {
view_query: &ViewQuery<'_>,
view_ctx: &ViewContextCollection,
) -> Result<Vec<re_renderer::QueueableDrawData>, SpaceViewSystemExecutionError> {
let mut line_builder = LineDrawableBuilder::new(ctx.render_ctx);
let Some(render_ctx) = ctx.render_ctx else {
return Err(SpaceViewSystemExecutionError::NoRenderContextError);
};

let mut line_builder = LineDrawableBuilder::new(render_ctx);
line_builder.radius_boost_in_ui_points_for_outlines(SIZE_BOOST_IN_POINTS_FOR_LINE_OUTLINES);

super::entity_iterator::process_archetype::<Self, Arrows3D, _>(
Expand Down
19 changes: 16 additions & 3 deletions crates/re_space_view_spatial/src/visualizers/assets3d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use re_entity_db::EntityPath;
use re_log_types::{Instance, RowId, TimeInt};
use re_query::range_zip_1x2;
use re_renderer::renderer::MeshInstance;
use re_renderer::RenderContext;
use re_types::{
archetypes::Asset3D,
components::{Blob, MediaType, OutOfTreeTransform3D},
Expand Down Expand Up @@ -44,6 +45,7 @@ impl Asset3DVisualizer {
fn process_data<'a>(
&mut self,
ctx: &ViewerContext<'_>,
render_ctx: &RenderContext,
instances: &mut Vec<MeshInstance>,
entity_path: &EntityPath,
ent_context: &SpatialSceneEntityContext<'_>,
Expand Down Expand Up @@ -73,7 +75,7 @@ impl Asset3DVisualizer {
media_type: data.media_type.cloned(),
},
AnyMesh::Asset(&mesh),
ctx.render_ctx,
render_ctx,
)
});

Expand Down Expand Up @@ -133,6 +135,10 @@ impl VisualizerSystem for Asset3DVisualizer {
view_query: &ViewQuery<'_>,
view_ctx: &ViewContextCollection,
) -> Result<Vec<re_renderer::QueueableDrawData>, SpaceViewSystemExecutionError> {
let Some(render_ctx) = ctx.render_ctx else {
return Err(SpaceViewSystemExecutionError::NoRenderContextError);
};

let mut instances = Vec::new();

super::entity_iterator::process_archetype::<Self, Asset3D, _>(
Expand Down Expand Up @@ -169,12 +175,19 @@ impl VisualizerSystem for Asset3DVisualizer {
})
});

self.process_data(ctx, &mut instances, entity_path, spatial_ctx, data);
self.process_data(
ctx,
render_ctx,
&mut instances,
entity_path,
spatial_ctx,
data,
);
Ok(())
},
)?;

match re_renderer::renderer::MeshDrawData::new(ctx.render_ctx, &instances) {
match re_renderer::renderer::MeshDrawData::new(render_ctx, &instances) {
Ok(draw_data) => Ok(vec![draw_data.into()]),
Err(err) => {
re_log::error_once!("Failed to create mesh draw data from mesh instances: {err}");
Expand Down
Loading

0 comments on commit 68a1061

Please sign in to comment.