diff options
Diffstat (limited to 'wgpu/src/texture')
-rw-r--r-- | wgpu/src/texture/atlas.rs | 38 | ||||
-rw-r--r-- | wgpu/src/texture/atlas/allocator.rs | 57 |
2 files changed, 57 insertions, 38 deletions
diff --git a/wgpu/src/texture/atlas.rs b/wgpu/src/texture/atlas.rs index 3d4e81c1..a76c035b 100644 --- a/wgpu/src/texture/atlas.rs +++ b/wgpu/src/texture/atlas.rs @@ -112,11 +112,47 @@ impl Atlas { } } - log::info!("Current atlas: {:?}", &self); + log::info!("Current atlas: {:?}", self); Some(entry) } + pub fn remove(&mut self, entry: &Entry) { + log::info!("Removing atlas entry: {:?}", entry); + + match entry { + Entry::Contiguous(allocation) => { + self.deallocate(allocation); + } + Entry::Fragmented { fragments, .. } => { + for fragment in fragments { + self.deallocate(&fragment.allocation); + } + } + } + } + + fn deallocate(&mut self, allocation: &Allocation) { + log::info!("Deallocating atlas: {:?}", allocation); + + match allocation { + Allocation::Full { layer } => { + self.layers[*layer] = Layer::Empty; + } + Allocation::Partial { layer, region } => { + let layer = &mut self.layers[*layer]; + + if let Layer::Busy(allocator) = layer { + allocator.deallocate(region); + + if allocator.is_empty() { + *layer = Layer::Empty; + } + } + } + } + } + fn allocate(&mut self, width: u32, height: u32) -> Option<Entry> { // Allocate one layer if texture fits perfectly if width == SIZE && height == SIZE { diff --git a/wgpu/src/texture/atlas/allocator.rs b/wgpu/src/texture/atlas/allocator.rs index ad111212..7a4ff5b1 100644 --- a/wgpu/src/texture/atlas/allocator.rs +++ b/wgpu/src/texture/atlas/allocator.rs @@ -2,70 +2,54 @@ use guillotiere::{AtlasAllocator, Size}; pub struct Allocator { raw: AtlasAllocator, - size: u32, + allocations: usize, } impl Allocator { - const PADDING: u32 = 1; - pub fn new(size: u32) -> Allocator { let raw = AtlasAllocator::new(Size::new(size as i32, size as i32)); - Allocator { raw, size } + Allocator { + raw, + allocations: 0, + } } pub fn allocate(&mut self, width: u32, height: u32) -> Option<Region> { - let padding = ( - if width + Self::PADDING * 2 < self.size { - Self::PADDING - } else { - 0 - }, - if height + Self::PADDING * 2 < self.size { - Self::PADDING - } else { - 0 - }, - ); - - let allocation = self.raw.allocate(Size::new( - (width + padding.0 * 2) as i32, - (height + padding.1 * 2) as i32, - ))?; - - Some(Region { - allocation, - padding, - }) + let allocation = + self.raw.allocate(Size::new(width as i32, height as i32))?; + + self.allocations += 1; + + Some(Region { allocation }) } - pub fn deallocate(&mut self, region: Region) { + pub fn deallocate(&mut self, region: &Region) { self.raw.deallocate(region.allocation.id); + + self.allocations = self.allocations.saturating_sub(1); + } + + pub fn is_empty(&self) -> bool { + self.allocations == 0 } } pub struct Region { allocation: guillotiere::Allocation, - padding: (u32, u32), } impl Region { pub fn position(&self) -> (u32, u32) { let rectangle = &self.allocation.rectangle; - ( - rectangle.min.x as u32 + self.padding.0, - rectangle.min.y as u32 + self.padding.1, - ) + (rectangle.min.x as u32, rectangle.min.y as u32) } pub fn size(&self) -> (u32, u32) { let size = self.allocation.rectangle.size(); - ( - size.width as u32 - self.padding.0 * 2, - size.height as u32 - self.padding.1 * 2, - ) + (size.width as u32, size.height as u32) } } @@ -80,7 +64,6 @@ impl std::fmt::Debug for Region { f.debug_struct("Region") .field("id", &self.allocation.id) .field("rectangle", &self.allocation.rectangle) - .field("padding", &self.padding) .finish() } } |