clean dropped video textures/buffers

This commit is contained in:
jazzfool 2024-10-06 22:18:43 +11:00
parent 877f5c906c
commit cd978e34e5
2 changed files with 44 additions and 7 deletions

View file

@ -2,7 +2,10 @@ use iced_wgpu::primitive::Primitive;
use iced_wgpu::wgpu; use iced_wgpu::wgpu;
use std::{ use std::{
collections::BTreeMap, collections::BTreeMap,
sync::{Arc, Mutex}, sync::{
atomic::{AtomicBool, Ordering},
Arc, Mutex,
},
}; };
#[repr(C)] #[repr(C)]
@ -14,7 +17,16 @@ struct VideoPipeline {
pipeline: wgpu::RenderPipeline, pipeline: wgpu::RenderPipeline,
bg0_layout: wgpu::BindGroupLayout, bg0_layout: wgpu::BindGroupLayout,
sampler: wgpu::Sampler, sampler: wgpu::Sampler,
textures: BTreeMap<u64, (wgpu::Texture, wgpu::Texture, wgpu::Buffer, wgpu::BindGroup)>, textures: BTreeMap<
u64,
(
wgpu::Texture,
wgpu::Texture,
wgpu::Buffer,
wgpu::BindGroup,
Arc<AtomicBool>,
),
>,
} }
impl VideoPipeline { impl VideoPipeline {
@ -127,6 +139,7 @@ impl VideoPipeline {
device: &wgpu::Device, device: &wgpu::Device,
queue: &wgpu::Queue, queue: &wgpu::Queue,
video_id: u64, video_id: u64,
alive: &Arc<AtomicBool>,
(width, height): (u32, u32), (width, height): (u32, u32),
frame: &[u8], frame: &[u8],
) { ) {
@ -217,11 +230,13 @@ impl VideoPipeline {
], ],
}); });
self.textures self.textures.insert(
.insert(video_id, (texture_y, texture_uv, buffer, bind_group)); video_id,
(texture_y, texture_uv, buffer, bind_group, Arc::clone(alive)),
);
} }
let (texture_y, texture_uv, _, _) = self.textures.get(&video_id).unwrap(); let (texture_y, texture_uv, _, _, _) = self.textures.get(&video_id).unwrap();
queue.write_texture( queue.write_texture(
wgpu::ImageCopyTexture { wgpu::ImageCopyTexture {
@ -264,8 +279,23 @@ impl VideoPipeline {
); );
} }
fn cleanup(&mut self) {
let ids: Vec<_> = self
.textures
.iter()
.filter_map(|(id, (_, _, _, _, alive))| (!alive.load(Ordering::SeqCst)).then_some(*id))
.collect();
for id in ids {
if let Some((texture_y, texture_uv, buffer, _, _)) = self.textures.remove(&id) {
texture_y.destroy();
texture_uv.destroy();
buffer.destroy();
}
}
}
fn prepare(&mut self, queue: &wgpu::Queue, video_id: u64, bounds: &iced::Rectangle) { fn prepare(&mut self, queue: &wgpu::Queue, video_id: u64, bounds: &iced::Rectangle) {
if let Some((_, _, buffer, _)) = self.textures.get(&video_id) { if let Some((_, _, buffer, _, _)) = self.textures.get(&video_id) {
let uniforms = Uniforms { let uniforms = Uniforms {
rect: [ rect: [
bounds.x, bounds.x,
@ -281,6 +311,8 @@ impl VideoPipeline {
) )
}); });
} }
self.cleanup();
} }
fn draw( fn draw(
@ -290,7 +322,7 @@ impl VideoPipeline {
viewport: &iced::Rectangle<u32>, viewport: &iced::Rectangle<u32>,
video_id: u64, video_id: u64,
) { ) {
if let Some((_, _, _, bind_group)) = self.textures.get(&video_id) { if let Some((_, _, _, bind_group, _)) = self.textures.get(&video_id) {
let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: Some("iced_video_player render pass"), label: Some("iced_video_player render pass"),
color_attachments: &[Some(wgpu::RenderPassColorAttachment { color_attachments: &[Some(wgpu::RenderPassColorAttachment {
@ -324,6 +356,7 @@ impl VideoPipeline {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub(crate) struct VideoPrimitive { pub(crate) struct VideoPrimitive {
video_id: u64, video_id: u64,
alive: Arc<AtomicBool>,
frame: Arc<Mutex<Vec<u8>>>, frame: Arc<Mutex<Vec<u8>>>,
size: (u32, u32), size: (u32, u32),
upload_frame: bool, upload_frame: bool,
@ -332,12 +365,14 @@ pub(crate) struct VideoPrimitive {
impl VideoPrimitive { impl VideoPrimitive {
pub fn new( pub fn new(
video_id: u64, video_id: u64,
alive: Arc<AtomicBool>,
frame: Arc<Mutex<Vec<u8>>>, frame: Arc<Mutex<Vec<u8>>>,
size: (u32, u32), size: (u32, u32),
upload_frame: bool, upload_frame: bool,
) -> Self { ) -> Self {
VideoPrimitive { VideoPrimitive {
video_id, video_id,
alive,
frame, frame,
size, size,
upload_frame, upload_frame,
@ -366,6 +401,7 @@ impl Primitive for VideoPrimitive {
device, device,
queue, queue,
self.video_id, self.video_id,
&self.alive,
self.size, self.size,
self.frame.lock().expect("lock frame mutex").as_slice(), self.frame.lock().expect("lock frame mutex").as_slice(),
); );

View file

@ -182,6 +182,7 @@ where
drawing_bounds, drawing_bounds,
VideoPrimitive::new( VideoPrimitive::new(
inner.id, inner.id,
Arc::clone(&inner.alive),
Arc::clone(&inner.frame), Arc::clone(&inner.frame),
(inner.width as _, inner.height as _), (inner.width as _, inner.height as _),
upload_frame, upload_frame,