Skip to main content

TileAtlas

Struct TileAtlas 

Source
pub struct TileAtlas { /* private fields */ }
Expand description

Tile texture atlas – packs individual tile images into shared GPU textures.

Manages one or more [AtlasPage]s and maintains a TileId -> AtlasRegion lookup table. New pages are lazily allocated when all existing pages are full; pages are never deallocated (their slots are recycled instead).

§Lifecycle (called by WgpuMapRenderer)

  1. Insertinsert enqueues a deferred upload.
  2. Flushflush_uploads writes all pending slot data to the GPU in one batched pass.
  3. Markmark_used for every tile drawn.
  4. Evictend_frame once after submit; optionally compacts the atlas when fragmentation is high.

§Deferred upload

Tile pixel data is not written to the GPU during insert. Instead, only the atlas slot is allocated and a [PendingUpload] is enqueued. The actual queue.write_texture calls happen during flush_uploads, which the renderer calls once per frame before building batched geometry. This ensures that only the affected slot’s pixel rectangle is uploaded (partial write), and all uploads are grouped into a single submission window.

§VRAM budget

Each page consumes 4096 x 4096 x 4 = 64 MiB. At moderate zoom levels a single page (256 slots) is sufficient; at very high zoom with a large viewport, 2-3 pages may be needed.

Implementations§

Source§

impl TileAtlas

Source

pub fn new() -> Self

Create an empty tile atlas. No GPU memory is allocated until the first insert call.

Source

pub fn get(&self, id: &TileId) -> Option<&AtlasRegion>

Look up where a tile is stored. Returns None if the tile has not been uploaded.

Source

pub fn contains(&self, id: &TileId) -> bool

Check whether a tile is present in the atlas.

Source

pub fn len(&self) -> usize

Total number of tiles currently stored across all pages.

Source

pub fn is_empty(&self) -> bool

Whether the atlas contains zero tiles.

Source

pub fn page_count(&self) -> usize

Number of atlas pages currently allocated.

Source

pub fn insert( &mut self, device: &Device, id: TileId, image: &DecodedImage, ) -> AtlasRegion

Enqueue a decoded tile image for deferred GPU upload.

If the tile is already present this is a no-op and returns the existing region. Otherwise a free slot is allocated (creating a new atlas page when necessary), the mip chain is pre-computed on the CPU, and a [PendingUpload] is enqueued. The actual GPU write happens later when flush_uploads is called.

§Arguments
  • device – WGPU device, used only if a new atlas page must be created.
  • id – The tile identity.
  • image – Decoded RGBA8 tile imagery used to generate all mip levels.
§Panics

Panics (via expect) if a freshly created atlas page has no free slots, which cannot happen by construction.

Source

pub fn flush_uploads(&mut self, queue: &Queue) -> usize

Flush all pending tile uploads to the GPU.

Each enqueued [PendingUpload] writes only the affected slot’s pixel rectangle via queue.write_texture - the rest of the atlas page is left untouched. This is the “partial texture write” path that replaces the previous full-page re-upload approach.

Call once per frame, after all insert calls and before building batched geometry.

Returns the number of tiles that were uploaded this frame.

Source

pub fn mark_used(&mut self, id: &TileId)

Mark a tile as used this frame (prevents eviction at end-of-frame).

Call this for every TileId that participates in the current frame’s draw calls – both imagery tiles and terrain tiles.

Source

pub fn end_frame(&mut self)

End-of-frame housekeeping: evict unused slots and optionally compact.

Call once after queue.submit(). Tiles that were not mark_used this frame have their slots freed and their regions entries removed.

When overall fragmentation exceeds 30% of allocated capacity, a compaction pass repacks all live tiles into the fewest contiguous slots and frees trailing empty pages.

Source

pub fn remove(&mut self, id: &TileId)

Remove a specific tile from the atlas, freeing its slot immediately.

Source

pub fn fragmentation_ratio(&self) -> f32

Fraction of allocated capacity that is empty (fragmented).

Returns 0.0 when there are no pages, and approaches 1.0 when most allocated slots are free. Used by end_frame to decide whether compaction is worthwhile.

Source

pub fn diagnostics(&self) -> AtlasDiagnostics

Snapshot of atlas health metrics for the current frame.

The returned AtlasDiagnostics exposes page count, slot utilisation, bytes uploaded this frame, and the current fragmentation ratio - all useful for performance overlays and automated tests.

Trait Implementations§

Source§

impl Default for TileAtlas

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> Downcast<T> for T

Source§

fn downcast(&self) -> &T

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> Upcast<T> for T

Source§

fn upcast(&self) -> Option<&T>

Source§

impl<T> WasmNotSend for T
where T: Send,

Source§

impl<T> WasmNotSendSync for T

Source§

impl<T> WasmNotSync for T
where T: Sync,