(&mut self, frame: RenderFrame<'_>)
| 971 | pub hdr_mode: HdrMode, |
| 972 | pub shader_variant_mode: crate::ShaderVariantMode, |
| 973 | pub shadow_quality: crate::ShadowQuality, |
| 974 | /// `graphics.render_scale`: scene render res / surface res (0.25..=1.0). |
| 975 | /// Applied b4 the dimension + pixel-budget caps. |
| 976 | pub render_scale: f32, |
| 977 | /// `graphics.power_preference`: adapter pick handed to `request_adapter`. |
| 978 | pub power_preference: crate::PowerPreference, |
| 979 | } |
| 980 | |
| 981 | // Views built once w/ the textures: `ensure_camera_stream_target` rebuilds the |
| 982 | // whole struct on any resolution/shape change, so a stored view can never go |
| 983 | // stale. Cloning a view is a refcount bump; create_view is not. |
| 984 | struct GpuCameraStreamTarget { |
| 985 | texture: wgpu::Texture, |
| 986 | view: wgpu::TextureView, |
| 987 | post_input_view: Option<wgpu::TextureView>, |
| 988 | tonemap_input_view: Option<wgpu::TextureView>, |
| 989 | depth_view: Option<wgpu::TextureView>, |
| 990 | resolution: [u32; 2], |
| 991 | /// Target pixels already pass through stream tone mapping when true. |
| 992 | tone_mapped: bool, |
| 993 | post_view_key: u64, |
| 994 | } |
| 995 | |
| 996 | struct CameraStreamContentRevision { |
| 997 | draws: Arc<[CameraStreamDraw3DState]>, |
| 998 | draw_revision: u64, |
| 999 | sprites: Arc<[Sprite2DCommand]>, |
| 1000 | sprite_revision: u64, |
| 1001 | } |
| 1002 | |
| 1003 | fn update_camera_stream_content_revisions( |
| 1004 | revisions: &mut AHashMap<NodeID, CameraStreamContentRevision>, |
| 1005 | next_revision: &mut u64, |
| 1006 | node: NodeID, |
| 1007 | draws: &Arc<[CameraStreamDraw3DState]>, |
| 1008 | sprites: &Arc<[Sprite2DCommand]>, |
| 1009 | ) -> (u64, u64) { |
| 1010 | match revisions.entry(node) { |
| 1011 | std::collections::hash_map::Entry::Occupied(mut entry) => { |
| 1012 | let state = entry.get_mut(); |
| 1013 | // ptr_eq fast path: no upsert since last render leaves the same |
| 1014 | // Arc in the retained state, so skip the elementwise compare. On |
| 1015 | // equal content in a fresh allocation (no-op upsert), converge to |
| 1016 | // the new Arc so later frames hit the pointer check again. |
| 1017 | if !Arc::ptr_eq(&state.draws, draws) { |
| 1018 | if state.draws.as_ref() != draws.as_ref() { |
| 1019 | *next_revision = next_nonzero_generation(*next_revision); |
| 1020 | state.draw_revision = *next_revision; |
| 1021 | } |
| 1022 | state.draws = draws.clone(); |
| 1023 | } |
| 1024 | if !Arc::ptr_eq(&state.sprites, sprites) { |
| 1025 | if state.sprites.as_ref() != sprites.as_ref() { |
| 1026 | *next_revision = next_nonzero_generation(*next_revision); |
| 1027 | state.sprite_revision = *next_revision; |
| 1028 | } |
| 1029 | state.sprites = sprites.clone(); |
| 1030 | } |
no test coverage detected