use super::RenderObjectInstance;
use crate::render_features::render_features_prelude::*;
use std::marker::PhantomData;
use std::ops::Range;
pub struct ExtractJob<'extract, ExtractJobEntryPointsT: ExtractJobEntryPoints<'extract>> {
inner: ExtractJobEntryPointsT,
extract_context: RenderJobExtractContext<'extract>,
frame_packet: Option<Box<FramePacket<ExtractJobEntryPointsT::FramePacketDataT>>>,
#[allow(dead_code)]
debug_constants: &'static RenderFeatureDebugConstants,
_phantom: (PhantomData<&'extract ()>,),
}
impl<'extract, ExtractJobEntryPointsT: 'extract + ExtractJobEntryPoints<'extract>>
ExtractJob<'extract, ExtractJobEntryPointsT>
{
pub fn new(
inner: ExtractJobEntryPointsT,
extract_context: &RenderJobExtractContext<'extract>,
frame_packet: Box<FramePacket<ExtractJobEntryPointsT::FramePacketDataT>>,
) -> Self {
let debug_constants = inner.feature_debug_constants();
Self {
inner,
extract_context: extract_context.clone(),
frame_packet: Some(frame_packet),
debug_constants,
_phantom: Default::default(),
}
}
fn frame_packet(&self) -> &Option<Box<FramePacket<ExtractJobEntryPointsT::FramePacketDataT>>> {
&self.frame_packet
}
fn view_packets(&self) -> &Vec<ViewPacket<ExtractJobEntryPointsT::FramePacketDataT>> {
&self.frame_packet.as_ref().unwrap().view_packets()
}
fn render_object_instances(&self) -> &Vec<RenderObjectInstance> {
&self
.frame_packet
.as_ref()
.unwrap()
.render_object_instances()
}
fn force_to_extract_lifetime(
&self,
inner: &ExtractJobEntryPointsT,
) -> &'extract ExtractJobEntryPointsT {
unsafe {
std::mem::transmute::<_, &'extract ExtractJobEntryPointsT>(inner)
}
}
}
impl<'extract, ExtractJobEntryPointsT: 'extract + ExtractJobEntryPoints<'extract>>
RenderFeatureExtractJob<'extract> for ExtractJob<'extract, ExtractJobEntryPointsT>
{
fn begin_per_frame_extract(&self) {
profiling::scope!(self.debug_constants.begin_per_frame_extract);
let context =
ExtractPerFrameContext::new(&self.extract_context, self.frame_packet.as_ref().unwrap());
self.inner.begin_per_frame_extract(&context);
}
fn extract_render_object_instance(
&self,
visibility_resource: &VisibilityResource,
range: Range<usize>,
) {
if range.is_empty() {
return;
}
let mut job_context = {
let inner = self.force_to_extract_lifetime(&self.inner);
inner.new_render_object_instance_job_context()
};
if job_context.is_none() {
return;
}
profiling::scope!(self.debug_constants.extract_render_object_instance);
let job_context = job_context.as_mut().unwrap();
let frame_packet = self.frame_packet.as_ref().unwrap();
for id in range {
let context = ExtractRenderObjectInstanceContext::new(
&self.extract_context,
frame_packet,
visibility_resource,
id,
);
self.inner
.extract_render_object_instance(job_context, &context);
}
}
fn view_packet(
&self,
view_index: ViewFrameIndex,
) -> &dyn RenderFeatureViewPacket {
self.frame_packet()
.as_ref()
.unwrap()
.render_feature_view_packet(view_index)
}
fn extract_render_object_instance_per_view(
&self,
view_packet: &dyn RenderFeatureViewPacket,
visibility_resource: &VisibilityResource,
range: Range<usize>,
) {
if range.is_empty() {
return;
}
let mut job_context = {
let inner = self.force_to_extract_lifetime(&self.inner);
inner.new_render_object_instance_per_view_job_context()
};
if job_context.is_none() {
return;
}
profiling::scope!(self.debug_constants.extract_render_object_instance_per_view);
let job_context = job_context.as_mut().unwrap();
let frame_packet = self.frame_packet.as_ref().unwrap();
let view_packet: &ViewPacket<ExtractJobEntryPointsT::FramePacketDataT> =
view_packet.as_concrete();
for id in range {
let context = ExtractRenderObjectInstancePerViewContext::new(
&self.extract_context,
frame_packet,
view_packet,
visibility_resource,
id,
);
self.inner
.extract_render_object_instance_per_view(job_context, &context);
}
}
fn end_per_view_extract(
&self,
view_packet: &dyn RenderFeatureViewPacket,
) {
profiling::scope!(self.debug_constants.end_per_view_extract);
let view_packet: &ViewPacket<ExtractJobEntryPointsT::FramePacketDataT> =
view_packet.as_concrete();
let context = ExtractPerViewContext::new(
&self.extract_context,
self.frame_packet.as_ref().unwrap(),
view_packet,
);
self.inner.end_per_view_extract(&context);
}
fn end_per_frame_extract(&self) {
profiling::scope!(self.debug_constants.end_per_frame_extract);
let context =
ExtractPerFrameContext::new(&self.extract_context, self.frame_packet.as_ref().unwrap());
self.inner.end_per_frame_extract(&context);
}
fn num_views(&self) -> usize {
self.view_packets().len()
}
fn num_render_object_instances(&self) -> usize {
self.render_object_instances().len()
}
fn take_frame_packet(&mut self) -> Box<dyn RenderFeatureFramePacket> {
std::mem::take(&mut self.frame_packet).unwrap()
}
fn feature_debug_constants(&self) -> &'static RenderFeatureDebugConstants {
self.inner.feature_debug_constants()
}
fn feature_index(&self) -> RenderFeatureIndex {
self.inner.feature_index()
}
}