use std::cell::Cell;
use crate::{
lazy_resource::LazyGpuResource,
pipeline_compiler::{CompileLane, CompilerSend, PipelineCompiler},
pipeline_recorder::PipelineRecorder,
};
pub(crate) struct FixedPipeline {
resource: LazyGpuResource<wgpu::RenderPipeline>,
queued: Cell<bool>,
cached: Cell<bool>,
#[cfg(not(target_arch = "wasm32"))]
drawn: Cell<bool>,
}
impl FixedPipeline {
pub(crate) fn new(label: &'static str) -> Self {
Self {
resource: LazyGpuResource::new(label),
queued: Cell::new(false),
cached: Cell::new(false),
#[cfg(not(target_arch = "wasm32"))]
drawn: Cell::new(false),
}
}
pub(crate) fn for_draw(
&self,
recorder: &PipelineRecorder,
backend: wgpu::Backend,
create: impl FnOnce() -> wgpu::RenderPipeline,
) -> &wgpu::RenderPipeline {
#[cfg(not(target_arch = "wasm32"))]
if !self.drawn.replace(true) {
recorder.note_fixed(self.resource.label(), recorder.in_first_screen());
}
self.resource.for_draw(recorder, backend, create)
}
pub(crate) fn get(&self) -> Option<&wgpu::RenderPipeline> {
self.resource.get()
}
pub(crate) fn queue(
&self,
compiler: &PipelineCompiler,
lane: CompileLane,
backend: wgpu::Backend,
create: impl FnOnce() -> wgpu::RenderPipeline + CompilerSend + 'static,
) {
if self.resource.get().is_none() && !self.queued.replace(true) {
self.resource.queue(compiler, lane, backend, create);
}
}
pub(crate) fn ready_or_queue<J>(
&self,
compiler: &PipelineCompiler,
backend: wgpu::Backend,
job: impl FnOnce() -> J,
) -> bool
where
J: FnOnce() -> wgpu::RenderPipeline + CompilerSend + 'static,
{
if self.resource.get().is_some() || self.cached.get() {
return true;
}
if compiler.is_active() {
self.queue(compiler, CompileLane::Demanded, backend, job());
return false;
}
true
}
#[cfg(not(target_arch = "wasm32"))]
pub(crate) fn trust_cached(&self) {
self.cached.set(true);
}
#[cfg(not(target_arch = "wasm32"))]
pub(crate) fn label(&self) -> &'static str {
self.resource.label()
}
}