rafx_framework/render_features/jobs/extract/
extract_job.rs1use super::RenderObjectInstance;
2use crate::render_features::render_features_prelude::*;
3use std::marker::PhantomData;
4use std::ops::Range;
5
6pub struct ExtractJob<'extract, ExtractJobEntryPointsT: ExtractJobEntryPoints<'extract>> {
11 inner: ExtractJobEntryPointsT,
12 extract_context: RenderJobExtractContext<'extract>,
13 frame_packet: Option<Box<FramePacket<ExtractJobEntryPointsT::FramePacketDataT>>>,
14 #[allow(dead_code)]
15 debug_constants: &'static RenderFeatureDebugConstants,
16 _phantom: (PhantomData<&'extract ()>,),
17}
18
19impl<'extract, ExtractJobEntryPointsT: 'extract + ExtractJobEntryPoints<'extract>>
20 ExtractJob<'extract, ExtractJobEntryPointsT>
21{
22 pub fn new(
23 inner: ExtractJobEntryPointsT,
24 extract_context: &RenderJobExtractContext<'extract>,
25 frame_packet: Box<FramePacket<ExtractJobEntryPointsT::FramePacketDataT>>,
26 ) -> Self {
27 let debug_constants = inner.feature_debug_constants();
28 Self {
29 inner,
30 extract_context: extract_context.clone(),
31 frame_packet: Some(frame_packet),
32 debug_constants,
33 _phantom: Default::default(),
34 }
35 }
36
37 fn frame_packet(&self) -> &Option<Box<FramePacket<ExtractJobEntryPointsT::FramePacketDataT>>> {
38 &self.frame_packet
39 }
40
41 fn view_packets(&self) -> &Vec<ViewPacket<ExtractJobEntryPointsT::FramePacketDataT>> {
42 &self.frame_packet.as_ref().unwrap().view_packets()
43 }
44
45 fn render_object_instances(&self) -> &Vec<RenderObjectInstance> {
46 &self
47 .frame_packet
48 .as_ref()
49 .unwrap()
50 .render_object_instances()
51 }
52
53 fn force_to_extract_lifetime(
54 &self,
55 inner: &ExtractJobEntryPointsT,
56 ) -> &'extract ExtractJobEntryPointsT {
57 unsafe {
58 std::mem::transmute::<_, &'extract ExtractJobEntryPointsT>(inner)
62 }
63 }
64}
65
66impl<'extract, ExtractJobEntryPointsT: 'extract + ExtractJobEntryPoints<'extract>>
67 RenderFeatureExtractJob<'extract> for ExtractJob<'extract, ExtractJobEntryPointsT>
68{
69 fn begin_per_frame_extract(&self) {
70 profiling::scope!(self.debug_constants.begin_per_frame_extract);
71
72 let context =
73 ExtractPerFrameContext::new(&self.extract_context, self.frame_packet.as_ref().unwrap());
74 self.inner.begin_per_frame_extract(&context);
75 }
76
77 fn extract_render_object_instance(
78 &self,
79 visibility_resource: &VisibilityResource,
80 range: Range<usize>,
81 ) {
82 if range.is_empty() {
83 return;
84 }
85
86 let mut job_context = {
87 let inner = self.force_to_extract_lifetime(&self.inner);
88 inner.new_render_object_instance_job_context()
89 };
90
91 if job_context.is_none() {
92 return;
93 }
94
95 profiling::scope!(self.debug_constants.extract_render_object_instance);
96
97 let job_context = job_context.as_mut().unwrap();
98 let frame_packet = self.frame_packet.as_ref().unwrap();
99 for id in range {
100 let context = ExtractRenderObjectInstanceContext::new(
101 &self.extract_context,
102 frame_packet,
103 visibility_resource,
104 id,
105 );
106 self.inner
107 .extract_render_object_instance(job_context, &context);
108 }
109 }
110
111 fn view_packet(
112 &self,
113 view_index: ViewFrameIndex,
114 ) -> &dyn RenderFeatureViewPacket {
115 self.frame_packet()
116 .as_ref()
117 .unwrap()
118 .render_feature_view_packet(view_index)
119 }
120
121 fn extract_render_object_instance_per_view(
122 &self,
123 view_packet: &dyn RenderFeatureViewPacket,
124 visibility_resource: &VisibilityResource,
125 range: Range<usize>,
126 ) {
127 if range.is_empty() {
128 return;
129 }
130
131 let mut job_context = {
132 let inner = self.force_to_extract_lifetime(&self.inner);
133 inner.new_render_object_instance_per_view_job_context()
134 };
135
136 if job_context.is_none() {
137 return;
138 }
139
140 profiling::scope!(self.debug_constants.extract_render_object_instance_per_view);
141
142 let job_context = job_context.as_mut().unwrap();
143 let frame_packet = self.frame_packet.as_ref().unwrap();
144 let view_packet: &ViewPacket<ExtractJobEntryPointsT::FramePacketDataT> =
145 view_packet.as_concrete();
146
147 for id in range {
148 let context = ExtractRenderObjectInstancePerViewContext::new(
149 &self.extract_context,
150 frame_packet,
151 view_packet,
152 visibility_resource,
153 id,
154 );
155 self.inner
156 .extract_render_object_instance_per_view(job_context, &context);
157 }
158 }
159
160 fn end_per_view_extract(
161 &self,
162 view_packet: &dyn RenderFeatureViewPacket,
163 ) {
164 profiling::scope!(self.debug_constants.end_per_view_extract);
165
166 let view_packet: &ViewPacket<ExtractJobEntryPointsT::FramePacketDataT> =
167 view_packet.as_concrete();
168
169 let context = ExtractPerViewContext::new(
170 &self.extract_context,
171 self.frame_packet.as_ref().unwrap(),
172 view_packet,
173 );
174 self.inner.end_per_view_extract(&context);
175 }
176
177 fn end_per_frame_extract(&self) {
178 profiling::scope!(self.debug_constants.end_per_frame_extract);
179
180 let context =
181 ExtractPerFrameContext::new(&self.extract_context, self.frame_packet.as_ref().unwrap());
182 self.inner.end_per_frame_extract(&context);
183 }
184
185 fn num_views(&self) -> usize {
186 self.view_packets().len()
187 }
188
189 fn num_render_object_instances(&self) -> usize {
190 self.render_object_instances().len()
191 }
192
193 fn take_frame_packet(&mut self) -> Box<dyn RenderFeatureFramePacket> {
194 std::mem::take(&mut self.frame_packet).unwrap()
195 }
196
197 fn feature_debug_constants(&self) -> &'static RenderFeatureDebugConstants {
198 self.inner.feature_debug_constants()
199 }
200
201 fn feature_index(&self) -> RenderFeatureIndex {
202 self.inner.feature_index()
203 }
204}