Another project
0

Configure Feed

Select the types of activity you want to include in your feed.

1pub mod camera; 2pub mod diff; 3pub mod gpu; 4pub mod pick; 5pub mod pipelines; 6pub mod preview; 7pub mod scene; 8pub mod snapshot; 9pub mod surface; 10 11pub use camera::{Camera2, GridSpacing, PixelsPerMm, ViewportExtent, ViewportPx}; 12pub use diff::{PixelDiff, PixelDiffError, PixelDiffReport, PixelDiffThreshold, PixelMismatch}; 13pub use gpu::{BackendTag, Capabilities, Gpu, OffscreenContext}; 14pub use pick::{EntityKindTag, PickId, PickIdError, PickIndex, PickQuery, PickedItem, Picker}; 15pub use pipelines::{ 16 ArcPipeline, ChromeInstance, ChromePipeline, ChromeTextPipeline, GlyphPipeline, GridPipeline, 17 LinesPipeline, SdfGlyphInstance, TextPipeline, 18}; 19pub use preview::{PreviewArc, PreviewCircle, SketchPreview}; 20pub use scene::{ 21 RelationGlyphKind, SceneArc, SceneCircle, SceneDimension, SceneLine, ScenePoint, 22 SceneRelationGlyph, SketchScene, 23}; 24pub use snapshot::{ 25 ClearColor, GlyphStyle, GridStyle, SnapshotFrame, StrokeStyle, Style, TextStyle, decode_png, 26 encode_png, 27}; 28pub use surface::{SurfaceContext, SurfaceError}; 29 30#[derive(Copy, Clone)] 31pub struct RenderTargets<'a> { 32 pub color: &'a wgpu::TextureView, 33 pub pick: &'a wgpu::TextureView, 34} 35 36impl<'a> RenderTargets<'a> { 37 #[must_use] 38 pub const fn new(color: &'a wgpu::TextureView, pick: &'a wgpu::TextureView) -> Self { 39 Self { color, pick } 40 } 41} 42 43#[derive(Debug, thiserror::Error)] 44pub enum RenderError { 45 #[error("no wgpu adapter matched the offscreen request: {0}")] 46 NoAdapter(#[from] wgpu::RequestAdapterError), 47 #[error("wgpu device request failed: {0}")] 48 Device(#[from] wgpu::RequestDeviceError), 49 #[error("wgpu poll failed: {0}")] 50 Poll(wgpu::PollError), 51 #[error("wgpu buffer map failed: {0}")] 52 Map(wgpu::BufferAsyncError), 53 #[error("wgpu buffer map callback did not fire after poll")] 54 MapMissing, 55 #[error("png encode failed: {0}")] 56 PngEncode(#[from] png::EncodingError), 57 #[error("png decode failed: {0}")] 58 PngDecode(#[from] png::DecodingError), 59 #[error("png format unsupported: color={color_type:?}, depth={bit_depth:?}, require rgba8")] 60 PngFormat { 61 color_type: png::ColorType, 62 bit_depth: png::BitDepth, 63 }, 64 #[error("viewport dimension is zero")] 65 ZeroExtent, 66 #[error("pick id construction failed: {0}")] 67 PickId(#[from] PickIdError), 68 #[error("pick query {query} outside viewport {extent}")] 69 PickOutOfBounds { 70 query: PickQuery, 71 extent: ViewportExtent, 72 }, 73} 74 75pub type Result<T, E = RenderError> = core::result::Result<T, E>; 76 77#[derive(Debug)] 78pub struct SketchRenderer { 79 grid: GridPipeline, 80 arcs: ArcPipeline, 81 lines: LinesPipeline, 82 glyphs: GlyphPipeline, 83 text: TextPipeline, 84} 85 86impl SketchRenderer { 87 #[must_use] 88 pub fn new(gpu: &Gpu, color_format: wgpu::TextureFormat) -> Self { 89 Self { 90 grid: GridPipeline::new(gpu, color_format), 91 arcs: ArcPipeline::new(gpu, color_format), 92 lines: LinesPipeline::new(gpu, color_format), 93 glyphs: GlyphPipeline::new(gpu, color_format), 94 text: TextPipeline::new(gpu, color_format), 95 } 96 } 97 98 pub fn prepare(&mut self, scene: &SketchScene, style: &Style) { 99 self.text.prepare(scene, style); 100 } 101 102 #[must_use] 103 pub fn text_cache_len(&self) -> usize { 104 self.text.cache_len() 105 } 106 107 pub fn encode_passes( 108 &self, 109 encoder: &mut wgpu::CommandEncoder, 110 targets: RenderTargets<'_>, 111 scene: &SketchScene, 112 preview: &SketchPreview, 113 camera: Camera2, 114 style: &Style, 115 ) { 116 self.grid.draw(encoder, targets.color, camera, style); 117 gpu::clear_pick_attachment(encoder, targets.pick); 118 self.arcs 119 .draw(encoder, targets, camera, style, scene, preview); 120 self.lines 121 .draw(encoder, targets, camera, style, scene, preview); 122 self.glyphs.draw(encoder, targets, camera, style, scene); 123 self.text.draw(encoder, targets, camera, style, scene); 124 } 125 126 pub fn render( 127 &mut self, 128 ctx: &OffscreenContext, 129 scene: &SketchScene, 130 camera: Camera2, 131 style: &Style, 132 ) -> Result<SnapshotFrame> { 133 self.render_with_preview(ctx, scene, &SketchPreview::empty(), camera, style) 134 } 135 136 pub fn render_with_preview( 137 &mut self, 138 ctx: &OffscreenContext, 139 scene: &SketchScene, 140 preview: &SketchPreview, 141 camera: Camera2, 142 style: &Style, 143 ) -> Result<SnapshotFrame> { 144 debug_assert_eq!( 145 camera.extent(), 146 ctx.extent(), 147 "camera extent must match offscreen context extent", 148 ); 149 self.prepare(scene, style); 150 ctx.render(|encoder, color_view, pick_view| { 151 self.encode_passes( 152 encoder, 153 RenderTargets::new(color_view, pick_view), 154 scene, 155 preview, 156 camera, 157 style, 158 ); 159 }) 160 } 161}