clean dropped video textures/buffers
This commit is contained in:
parent
877f5c906c
commit
cd978e34e5
2 changed files with 44 additions and 7 deletions
|
@ -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(),
|
||||||
);
|
);
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue