From 616a3dd849c87db72db37d534bb21ddc700a2165 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Fri, 22 Feb 2019 22:23:52 -0500 Subject: [PATCH] Fix leaking swapchain textures --- wgpu-native/src/device.rs | 22 +++++++++++++++------- wgpu-rs/src/lib.rs | 19 ++++++++++++++++--- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/wgpu-native/src/device.rs b/wgpu-native/src/device.rs index 0bee3e49d3..a7da89d545 100644 --- a/wgpu-native/src/device.rs +++ b/wgpu-native/src/device.rs @@ -15,9 +15,11 @@ use crate::{ }; use back; +use hal::backend::FastHashMap; use hal::command::RawCommandBuffer; use hal::queue::RawCommandQueue; -use hal::{self, +use hal::{ + self, DescriptorPool as _DescriptorPool, Device as _Device, Surface as _Surface, @@ -27,7 +29,7 @@ use log::{info, trace}; use parking_lot::{Mutex}; use std::{ffi, iter, slice}; -use std::collections::hash_map::{Entry, HashMap}; +use std::collections::hash_map::Entry; use std::sync::atomic::Ordering; @@ -64,7 +66,7 @@ pub(crate) struct FramebufferKey { } impl Eq for FramebufferKey {} -#[derive(Debug)] +#[derive(Debug, PartialEq)] enum ResourceId { Buffer(BufferId), Texture(TextureId), @@ -100,6 +102,7 @@ unsafe impl Sync for DestroyedResources {} impl DestroyedResources { fn add(&mut self, resource_id: ResourceId, ref_count: RefCount) { + debug_assert!(!self.referenced.iter().any(|r| r.0 == resource_id)); self.referenced.push((resource_id, ref_count)); } @@ -195,8 +198,8 @@ pub struct Device { life_guard: LifeGuard, pub(crate) trackers: Mutex, mem_props: hal::MemoryProperties, - pub(crate) render_passes: Mutex>, - pub(crate) framebuffers: Mutex>, + pub(crate) render_passes: Mutex>, + pub(crate) framebuffers: Mutex>, desc_pool: Mutex, destroyed: Mutex>, } @@ -269,8 +272,8 @@ impl Device { life_guard, trackers: Mutex::new(TrackerSet::new()), mem_props, - render_passes: Mutex::new(HashMap::new()), - framebuffers: Mutex::new(HashMap::new()), + render_passes: Mutex::new(FastHashMap::default()), + framebuffers: Mutex::new(FastHashMap::default()), desc_pool, destroyed: Mutex::new(DestroyedResources { referenced: Vec::new(), @@ -1380,7 +1383,12 @@ pub fn device_create_swap_chain( let (old_raw, sem_available, command_pool) = match surface.swap_chain.take() { Some(mut old) => { + let mut destroyed = device.destroyed.lock(); assert_eq!(old.device_id.value, device_id); + for frame in old.frames { + destroyed.add(ResourceId::Texture(frame.texture_id.value), frame.texture_id.ref_count); + destroyed.add(ResourceId::TextureView(frame.view_id.value), frame.view_id.ref_count); + } unsafe { old.command_pool.reset() }; diff --git a/wgpu-rs/src/lib.rs b/wgpu-rs/src/lib.rs index 5c2c5304a5..036c64d1c1 100644 --- a/wgpu-rs/src/lib.rs +++ b/wgpu-rs/src/lib.rs @@ -54,10 +54,12 @@ pub struct Buffer { pub struct Texture { id: wgn::TextureId, + owned: bool, } pub struct TextureView { id: wgn::TextureViewId, + owned: bool, } pub struct Sampler { @@ -427,6 +429,7 @@ impl Device { pub fn create_texture(&self, desc: &TextureDescriptor) -> Texture { Texture { id: wgn::wgpu_device_create_texture(self.id, desc), + owned: true, } } @@ -467,25 +470,31 @@ impl Texture { pub fn create_view(&self, desc: &TextureViewDescriptor) -> TextureView { TextureView { id: wgn::wgpu_texture_create_view(self.id, desc), + owned: true, } } pub fn create_default_view(&self) -> TextureView { TextureView { id: wgn::wgpu_texture_create_default_view(self.id), + owned: true, } } } impl Drop for Texture { fn drop(&mut self) { - wgn::wgpu_texture_destroy(self.id); + if self.owned { + wgn::wgpu_texture_destroy(self.id); + } } } impl Drop for TextureView { fn drop(&mut self) { - wgn::wgpu_texture_view_destroy(self.id); + if self.owned { + wgn::wgpu_texture_view_destroy(self.id); + } } } @@ -707,8 +716,12 @@ impl SwapChain { SwapChainOutput { texture: Texture { id: output.texture_id, + owned: false, + }, + view: TextureView { + id: output.view_id, + owned: false, }, - view: TextureView { id: output.view_id }, swap_chain_id: &self.id, } }