pub struct AtlasSet<U: Hash + Eq + Clone = String, Data: Copy + Default = i32> {Show 15 fields
pub texture: Texture,
pub layers: Vec<Atlas>,
pub size: u32,
pub store: Slab<(Allocation<Data>, U)>,
pub lookup: AHashMap<U, usize>,
pub cache: LruCache<usize, usize>,
pub last_used: AHashSet<usize>,
pub format: TextureFormat,
pub max_layers: usize,
pub deallocations_limit: usize,
pub layer_check_limit: usize,
pub layer_free_limit: usize,
pub use_ref_count: bool,
pub texture_group: TextureGroup,
pub migration: Option<MigrationTask>,
}Expand description
AtlasSet is used to hold and contain the data of many Atlas layers. Each Atlas keeps track of the allocations allowed. Each allocation is a given Width/Height as well as Position that a Texture image can fit within the atlas.
We try to use Store to keep all Allocations localized so if they need to be unloaded, migrated or replaced then the system can prevent improper rendering using a outdated Allocation. We will also attempt to keep track of reference counts loading the Index and try to keep track of LRU cache and a list of last used Indexs. This will help reduce errors and can help to reduce Vram and Later Reduce Fragmentation of the Atlas.
FRAGMENTATION************* Fragmentation of a Atlas is when you Deallocate and Allocate new image textures into the Atlas. As this occurs there is a possibility that Small spots that can not be used in the Atlas to appear. These small Sections might get merged into larger Sections upon Deallocation of neighboring Allocations, But in some Cases these might over run the Atlas cuasing use to use way more Vram than is needed. To fix this we must migrate all loaded Allocations to a new Atlas and either move the old atlas to the back of the list for reuse or unload it. We can accomplish knowing when to migrate the atlas by setting a deallocations_limit. We also can know when to unload a empty layer by using the layer_free_limit. This will allow us to control VRam usage.
TODO Keep track of Indexs within an Atlas.
Fields§
§texture: TextureTexture in GRAM, Holds all the atlas layers.
layers: Vec<Atlas>Layers of texture.
size: u32Holds the Texture’s Size.
store: Slab<(Allocation<Data>, U)>Store the Allocations se we can easily remove and update them. use a Generation id to avoid conflict if users use older allocation id’s. Also stores the Key associated with the Allocation.
lookup: AHashMap<U, usize>for key to index lookups.
cache: LruCache<usize, usize>keeps a list of least used allocations so we can unload them when need be. Also include the RefCount per ID lookup. we use this to keep track of when Fonts need to be unloaded. this only helps to get memory back but does not fix fragmentation of the Atlas.
last_used: AHashSet<usize>List of allocations used in the last frame to ensure we dont unload what is in use.
format: TextureFormatFormat the Texture uses.
max_layers: usizeWhen the System will Error if reached. This is the max allowed Layers
Default is wgpu::Limits::max_texture_array_layers. Most GPU allow a max of 256.
deallocations_limit: usizeLimit of deallocations allowed before we attempt to migrate the textures allocations to fix fragmentation.
layer_check_limit: usizeamount of layers in memory before we start checking for fragmentations.
layer_free_limit: usizeWhen we should free empty layers. this must be more than 1 otherwise will cause issues.
use_ref_count: booluses the refcount to unload rather than the unused. must exist for fonts to unload correctly and must be set to false for them.
texture_group: TextureGroupTexture Bind group for Atlas Set
migration: Option<MigrationTask>Used to Migrate Textures to reduce Fragmentation.
Implementations§
Source§impl<U: Hash + Eq + Clone, Data: Copy + Default> AtlasSet<U, Data>
impl<U: Hash + Eq + Clone, Data: Copy + Default> AtlasSet<U, Data>
pub fn migrate_allocation( &mut self, old_allocation: &Allocation<Data>, allocation: &Allocation<Data>, encoder: &mut CommandEncoder, )
Source§impl<U: Hash + Eq + Clone, Data: Copy + Default> AtlasSet<U, Data>
impl<U: Hash + Eq + Clone, Data: Copy + Default> AtlasSet<U, Data>
Sourcepub fn new(
renderer: &mut GpuRenderer,
format: TextureFormat,
use_ref_count: bool,
size: u32,
) -> Self
pub fn new( renderer: &mut GpuRenderer, format: TextureFormat, use_ref_count: bool, size: u32, ) -> Self
Creates a new AtlasSet.
§Arguments
- format:
wgpu::TextureFormatthe texture layers will need to be. - use_ref_count: Mostly used for Glyph Storage and Auto Removal.
- size: Used for both Width and Height. Limited to max of limits.max_texture_dimension_2d and min of 256.
Sourcepub fn upload_allocation(
&mut self,
buffer: &[u8],
allocation: &Allocation<Data>,
renderer: &GpuRenderer,
)
pub fn upload_allocation( &mut self, buffer: &[u8], allocation: &Allocation<Data>, renderer: &GpuRenderer, )
Uploads a new Texture Byte Array into the GPU AtlasSets Layer.
Sourcepub fn clear(&mut self)
pub fn clear(&mut self)
Clears all information of stored Textures and Allocations.
This Does not Empty the AtlasSets GPU Texture Buffer.
As we normally just overwrite the buffer when we add new Allocations.
Sourcepub fn defragment(
&mut self,
renderer: &GpuRenderer,
) -> Result<bool, GraphicsError>
pub fn defragment( &mut self, renderer: &GpuRenderer, ) -> Result<bool, GraphicsError>
Defragments Textures when they reach a specific threshhold.
§Strategy
This Function Will check to see if a migration task exists yet. If not, it will check to see if any texture layers meet the criteria of needing to be defragmented. If they are the system will generate a Migration Task and place each possibly fragmented layer into a list, defragmenting one layer per call, until all layers marked for migrating are no longer in need of migrating.
§Suggested usage
Call this function about once every so many frame cycles. It can be a bit slow and could Impact FPS during its processing so we only attempt to migrate one layer at a time per each call.
§Returns
bool indicating if any migrations took place during this run cycle so you can rebuild your Objects in GPU Memory. Always use this to know when to Rebuild Otherwise Graphical errors can Occur.
Sourcepub fn promote_by_key(&mut self, key: U)
pub fn promote_by_key(&mut self, key: U)
Promotes the cache’s Allocation by key making it recently used..
Sourcepub fn promote(&mut self, id: usize)
pub fn promote(&mut self, id: usize)
Promotes the cache’s Allocation by index making it recently used..
Sourcepub fn peek_by_key(&mut self, key: &U) -> Option<&(Allocation<Data>, U)>
pub fn peek_by_key(&mut self, key: &U) -> Option<&(Allocation<Data>, U)>
Gets using key the reference of Allocation with key if it exists.
Sourcepub fn peek(&mut self, id: usize) -> Option<&(Allocation<Data>, U)>
pub fn peek(&mut self, id: usize) -> Option<&(Allocation<Data>, U)>
Gets using index the reference of Allocation with key if it exists.
Sourcepub fn contains_key(&mut self, key: &U) -> bool
pub fn contains_key(&mut self, key: &U) -> bool
If Allocation using key exists.
Sourcepub fn contains(&mut self, id: usize) -> bool
pub fn contains(&mut self, id: usize) -> bool
If Allocation at id exists.
Sourcepub fn get_by_key(&mut self, key: &U) -> Option<Allocation<Data>>
pub fn get_by_key(&mut self, key: &U) -> Option<Allocation<Data>>
Gets using key the Allocation if it exists.
Also Increments the Cache and adds to last_used list.
Sourcepub fn get(&mut self, id: usize) -> Option<Allocation<Data>>
pub fn get(&mut self, id: usize) -> Option<Allocation<Data>>
Gets using index the Allocation if it exists.
Also Increments the Cache and adds to last_used list.
Sourcepub fn remove_by_key(&mut self, key: &U) -> Option<usize>
pub fn remove_by_key(&mut self, key: &U) -> Option<usize>
Removed Texture by key. Removing will leave anything using the texture inable to load the correct texture if a new texture is loaded in the olds place.
returns the layer id if removed otherwise None for everything else.
Sourcepub fn remove(&mut self, id: usize) -> Option<usize>
pub fn remove(&mut self, id: usize) -> Option<usize>
Removed Texture by index. Removing will leave anything using the texture inable to load the correct texture if a new texture is loaded in the olds place.
returns the layer id if removed otherwise None for everything else.
Sourcepub fn upload(
&mut self,
key: U,
bytes: &[u8],
width: u32,
height: u32,
data: Data,
renderer: &GpuRenderer,
) -> Option<usize>
pub fn upload( &mut self, key: U, bytes: &[u8], width: u32, height: u32, data: Data, renderer: &GpuRenderer, ) -> Option<usize>
Uploads Texture byte array to the AtlasSet returning the created Allocations Index.
§Arguments
- bytes: Textures Byte array.
- width: Width of the Texture.
- height: Height of the Texture.
- data: any specail generic data for the texture.
Sourcepub fn upload_with_alloc(
&mut self,
key: U,
bytes: &[u8],
width: u32,
height: u32,
data: Data,
renderer: &GpuRenderer,
) -> Option<(usize, Allocation<Data>)>
pub fn upload_with_alloc( &mut self, key: U, bytes: &[u8], width: u32, height: u32, data: Data, renderer: &GpuRenderer, ) -> Option<(usize, Allocation<Data>)>
Uploads Texture byte array to the AtlasSet returning the created Allocation and Index.
§Arguments
- bytes: Textures Byte array.
- width: Width of the Texture.
- height: Height of the Texture.
- data: any specail generic data for the texture.
Sourcepub fn size(&self) -> UVec3
pub fn size(&self) -> UVec3
Returns the Width and Height of the AtlasSet and how many Layers Exist.
Sourcepub fn bind_group(&self) -> &BindGroup
pub fn bind_group(&self) -> &BindGroup
Returns a BindGroup Reference to the AtlasSets Texture Binding.
Sourcepub fn with_deallocations_limit(self, limit: usize) -> Self
pub fn with_deallocations_limit(self, limit: usize) -> Self
Returns a BindGroup Reference to the AtlasSets Texture Binding.
Auto Trait Implementations§
impl<U, Data> Freeze for AtlasSet<U, Data>
impl<U = String, Data = i32> !RefUnwindSafe for AtlasSet<U, Data>
impl<U, Data> Send for AtlasSet<U, Data>
impl<U, Data> Sync for AtlasSet<U, Data>
impl<U, Data> Unpin for AtlasSet<U, Data>
impl<U = String, Data = i32> !UnwindSafe for AtlasSet<U, Data>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more