use eframe::egui_wgpu::CallbackTrait;
use kanal::{Receiver, Sender, bounded};
use std::sync::LazyLock;
use wgpu::CommandBuffer;
static QUEUE: LazyLock<(Sender<CommandBuffer>, Receiver<CommandBuffer>)> =
LazyLock::new(|| bounded(16));
#[derive(Debug)]
pub(crate) struct RendererCallback;
impl RendererCallback {
#[cfg_attr(feature = "profiling", profiling::function)]
pub(crate) fn add(buffer: CommandBuffer) {
#[cfg(not(target_arch = "wasm32"))]
if QUEUE.0.send(buffer).is_err() {
tracing::warn!("The renderer callback queue is closed");
}
#[cfg(target_arch = "wasm32")]
Self::try_add(buffer);
}
}
impl RendererCallback {
pub(crate) fn try_add(buffer: CommandBuffer) {
let sent = QUEUE.0.try_send(buffer);
if !matches!(sent, Ok(true)) {
tracing::trace!("Renderer callback queue is full, dropped a command buffer");
}
}
}
impl CallbackTrait for RendererCallback {
fn paint(
&self,
_info: egui::PaintCallbackInfo,
_render_pass: &mut wgpu::RenderPass<'static>,
_callback_resources: &eframe::egui_wgpu::CallbackResources,
) {
}
#[cfg_attr(feature = "profiling", profiling::function)]
fn prepare(
&self,
_device: &wgpu::Device,
_queue: &wgpu::Queue,
_screen_descriptor: &eframe::egui_wgpu::ScreenDescriptor,
_egui_encoder: &mut wgpu::CommandEncoder,
_callback_resources: &mut eframe::egui_wgpu::CallbackResources,
) -> Vec<wgpu::CommandBuffer> {
let mut buffers = Vec::with_capacity(16);
while let Ok(Some(buffer)) = QUEUE.1.try_recv() {
buffers.push(buffer);
}
buffers
}
fn finish_prepare(
&self,
_device: &wgpu::Device,
_queue: &wgpu::Queue,
_egui_encoder: &mut wgpu::CommandEncoder,
_callback_resources: &mut eframe::egui_wgpu::CallbackResources,
) -> Vec<wgpu::CommandBuffer> {
Vec::new()
}
}