use crate::geom;
use crate::wgpu;
use crate::window;
use std::cell::{RefCell, RefMut};
use std::sync::Arc;
pub struct RawFrame<'swap_chain> {
command_encoder: Option<RefCell<wgpu::CommandEncoder>>,
window_id: window::Id,
nth: u64,
swap_chain_texture: &'swap_chain wgpu::TextureViewHandle,
device_queue_pair: Arc<wgpu::DeviceQueuePair>,
texture_format: wgpu::TextureFormat,
window_rect: geom::Rect,
}
impl<'swap_chain> RawFrame<'swap_chain> {
pub(crate) fn new_empty(
device_queue_pair: Arc<wgpu::DeviceQueuePair>,
window_id: window::Id,
nth: u64,
swap_chain_texture: &'swap_chain wgpu::TextureViewHandle,
texture_format: wgpu::TextureFormat,
window_rect: geom::Rect,
) -> Self {
let ce_desc = wgpu::CommandEncoderDescriptor {
label: Some("nannou_raw_frame"),
};
let command_encoder = device_queue_pair.device().create_command_encoder(&ce_desc);
let command_encoder = Some(RefCell::new(command_encoder));
let frame = RawFrame {
command_encoder,
window_id,
nth,
swap_chain_texture,
device_queue_pair,
texture_format,
window_rect,
};
frame
}
pub(crate) fn submit_inner(&mut self) {
let command_encoder = self
.command_encoder
.take()
.expect("the command encoder should always be `Some` at the time of submission")
.into_inner();
let command_buffer = command_encoder.finish();
let queue = self.device_queue_pair.queue();
queue.submit(std::iter::once(command_buffer));
}
pub(crate) fn is_submitted(&self) -> bool {
self.command_encoder.is_none()
}
pub fn command_encoder(&self) -> RefMut<wgpu::CommandEncoder> {
match self.command_encoder {
Some(ref ce) => ce.borrow_mut(),
None => unreachable!("`RawFrame`'s command_encoder was `None`"),
}
}
pub fn window_id(&self) -> window::Id {
self.window_id
}
pub fn rect(&self) -> geom::Rect {
self.window_rect
}
pub fn nth(&self) -> u64 {
self.nth
}
pub fn swap_chain_texture(&self) -> &wgpu::TextureViewHandle {
&self.swap_chain_texture
}
pub fn texture_format(&self) -> wgpu::TextureFormat {
self.texture_format
}
pub fn device_queue_pair(&self) -> &Arc<wgpu::DeviceQueuePair> {
&self.device_queue_pair
}
pub fn submit(mut self) {
self.submit_inner();
}
pub fn clear(&self, texture_view: &wgpu::TextureView, color: wgpu::Color) {
wgpu::clear_texture(texture_view, color, &mut *self.command_encoder())
}
}
impl<'swap_chain> Drop for RawFrame<'swap_chain> {
fn drop(&mut self) {
if !self.is_submitted() {
self.submit_inner();
}
}
}