Table of Contents

Class TileStreamer

Downloads, decodes, and uploads tiles into GPU residency each frame.

public sealed class TileStreamer : IDisposable, ITileResidency
Inheritance
object
TileStreamer
Implements

Remarks

Call Tick(MapViewTransform, double) once per frame from the main thread. This frame's upload pin set is applied before inserts, so admitted keys cannot be evicted this frame; PinHeadroomLayers layers stay evictable when capacity allows, otherwise one less than capacity. Decode and GPU upload share UploadBudgetMs; PNG and JPEG decode go to a managed worker when DecodeOffloadAllowed is true, and otherwise stay on the calling thread unless the constructor's webWorkerDecode is true (JS Worker; demo scenes turn this on). The cancel pass aborts in-flight scheduler fetches that left the wanted set and are still below 0.7 complete; past 0.7 the download keeps going and can still land, and a slot that already finished keeps its bytes. Parent, region, and floor prefetch never enter the scheduler; if they did, the wanted-set pass would cancel them every tick.

Constructors

TileStreamer(ITileDataSource, ITileAddressBuilder, TileBatchRenderer, ITileFetcher, string, int, TileCacheSettings?, bool, int, bool, bool, int, bool, IReadOnlyList<ITileBlockCodec>, bool, IWebTileDecodeBridge, bool, WebAstcEncoderQuality, Func<string, TileCacheSettings, ITilePersistentStore>)

Builds a streamer from any data source and address builder.

public TileStreamer(ITileDataSource source, ITileAddressBuilder addresses, TileBatchRenderer renderer, ITileFetcher fetcher, string cacheDirectory, int layerCount, TileCacheSettings? cacheSettings = null, bool startDecodeWorkerThread = true, int floorMaxZoom = 4, bool floorPrefetchEnabled = true, bool floorPinEnabled = true, int floorPinMaxZoom = 4, bool allowDecodeOffload = true, IReadOnlyList<ITileBlockCodec> extraCodecs = null, bool webWorkerDecode = false, IWebTileDecodeBridge webDecodeBridge = null, bool webGpuDirectUpload = false, WebAstcEncoderQuality webAstcEncoderQuality = WebAstcEncoderQuality.Fastest, Func<string, TileCacheSettings, ITilePersistentStore> storeFactory = null)

Parameters

source ITileDataSource

Tile metadata only (size, zoom range, cache key, attribution); bytes come from fetcher via addresses.

addresses ITileAddressBuilder

Builds the fetch URL or path for each tile.

renderer TileBatchRenderer

GPU tile array this streamer uploads into.

fetcher ITileFetcher

Transport slots that download tile bytes.

cacheDirectory string

Folder for tiles.dat and tiles.idx.

layerCount int

Resident Texture2DArray layers; must be positive.

cacheSettings TileCacheSettings?

Disk-cache cap and compaction; null uses Default.

startDecodeWorkerThread bool

False only in tests that decode synchronously; ANDed with allowDecodeOffload.

floorMaxZoom int

Deepest zoom of the idle disk-only world trickle.

floorPrefetchEnabled bool

Starts the idle disk trickle when the provider allows it.

floorPinEnabled bool

Pins loaded world-floor tiles in GPU memory.

floorPinMaxZoom int

Requested deepest pinned floor zoom; actual depth is capacity-derived.

allowDecodeOffload bool

True dispatches PNG/JPEG to a managed worker thread; false skips that worker, then PNG/JPEG stay inline unless webWorkerDecode is true.

extraCodecs IReadOnlyList<ITileBlockCodec>

Consumer-registered block codecs for disk-hit recognition; null is built-ins only.

webWorkerDecode bool

True probes a JS Worker decode path, only when allowDecodeOffload is false.

webDecodeBridge IWebTileDecodeBridge

Injected Web decode bridge for tests; null constructs the production bridge.

webGpuDirectUpload bool

True additionally probes the WebGPU direct-texture-upload path, only when webWorkerDecode is also true and the browser proves it can bind the live array.

webAstcEncoderQuality WebAstcEncoderQuality
storeFactory Func<string, TileCacheSettings, ITilePersistentStore>

TileStreamer(TileSource, TileBatchRenderer, ITileFetcher, string, int, TileCacheSettings?, bool, int, bool, bool, int, bool, IReadOnlyList<ITileBlockCodec>, bool, IWebTileDecodeBridge, bool, WebAstcEncoderQuality, Func<string, TileCacheSettings, ITilePersistentStore>)

Builds a streamer that derives fetch URLs from source.

public TileStreamer(TileSource source, TileBatchRenderer renderer, ITileFetcher fetcher, string cacheDirectory, int layerCount, TileCacheSettings? cacheSettings = null, bool startDecodeWorkerThread = true, int floorMaxZoom = 4, bool floorPrefetchEnabled = true, bool floorPinEnabled = true, int floorPinMaxZoom = 4, bool allowDecodeOffload = true, IReadOnlyList<ITileBlockCodec> extraCodecs = null, bool webWorkerDecode = false, IWebTileDecodeBridge webDecodeBridge = null, bool webGpuDirectUpload = false, WebAstcEncoderQuality webAstcEncoderQuality = WebAstcEncoderQuality.Fastest, Func<string, TileCacheSettings, ITilePersistentStore> storeFactory = null)

Parameters

source TileSource

Tile metadata only (size, zoom range, cache key, attribution); bytes come from fetcher.

renderer TileBatchRenderer

GPU tile array this streamer uploads into.

fetcher ITileFetcher

Transport slots that download tile bytes.

cacheDirectory string

Folder for tiles.dat and tiles.idx.

layerCount int

Resident Texture2DArray layers; must be positive.

cacheSettings TileCacheSettings?

Disk-cache cap and compaction; null uses Default.

startDecodeWorkerThread bool

False only in tests that decode synchronously; ANDed with allowDecodeOffload.

floorMaxZoom int

Deepest zoom of the idle disk-only world trickle.

floorPrefetchEnabled bool

Starts the idle disk trickle when the provider allows it.

floorPinEnabled bool

Pins loaded world-floor tiles in GPU memory.

floorPinMaxZoom int

Requested deepest pinned floor zoom; actual depth is capacity-derived.

allowDecodeOffload bool

True dispatches PNG/JPEG to a managed worker thread; false skips that worker, then PNG/JPEG stay inline unless webWorkerDecode is true.

extraCodecs IReadOnlyList<ITileBlockCodec>

Consumer-registered block codecs for disk-hit recognition; null is built-ins only.

webWorkerDecode bool

True probes a JS Worker decode path, only when allowDecodeOffload is false.

webDecodeBridge IWebTileDecodeBridge

Injected Web decode bridge for tests; null constructs the production bridge.

webGpuDirectUpload bool

True additionally probes the WebGPU direct-texture-upload path, only when webWorkerDecode is also true and the browser proves it can bind the live array.

webAstcEncoderQuality WebAstcEncoderQuality
storeFactory Func<string, TileCacheSettings, ITilePersistentStore>

Fields

AllowLocalCacheMigration

public bool AllowLocalCacheMigration

Field Value

bool

CoarsePrefetchDelta

public int CoarsePrefetchDelta

Field Value

int

DefaultAllowDecodeOffload

public const bool DefaultAllowDecodeOffload = true

Field Value

bool

DefaultAllowLocalCacheMigration

public const bool DefaultAllowLocalCacheMigration = true

Field Value

bool

DefaultCoarsePrefetchDelta

public const int DefaultCoarsePrefetchDelta = 0

Field Value

int

DefaultFadeAllLoads

public const bool DefaultFadeAllLoads = true

Field Value

bool

DefaultFetchDeadlineSeconds

public const double DefaultFetchDeadlineSeconds = 45

Field Value

double

DefaultInstanceTag

public const string DefaultInstanceTag = ""

Field Value

string

DefaultMaxDecodeQueue

public const int DefaultMaxDecodeQueue = 64

Field Value

int

DefaultPitchDistanceLodEnabled

public const bool DefaultPitchDistanceLodEnabled = false

Field Value

bool

DefaultPrefetchParentTiles

public const bool DefaultPrefetchParentTiles = true

Field Value

bool

DefaultTileFadeSeconds

public const double DefaultTileFadeSeconds = 0.2

Field Value

double

DefaultUploadBudgetMs

public const double DefaultUploadBudgetMs = 1.5

Field Value

double

DefaultVerbose

public const bool DefaultVerbose = false

Field Value

bool

DefaultZoomBlendEnabled

public const bool DefaultZoomBlendEnabled = false

Field Value

bool

DefaultZoomHysteresisSeconds

public const double DefaultZoomHysteresisSeconds = 30

Field Value

double

DefaultZoomLevelHysteresis

public const double DefaultZoomLevelHysteresis = 0.15

Field Value

double

FadeAllLoads

public bool FadeAllLoads

Field Value

bool

FetchDeadlineSeconds

public double FetchDeadlineSeconds

Field Value

double

InstanceTag

public string InstanceTag

Field Value

string

MaxCapacityLevelDrops

public const int MaxCapacityLevelDrops = 2

Field Value

int

MaxDecodeQueue

public int MaxDecodeQueue

Field Value

int

PinHeadroomLayers

public const int PinHeadroomLayers = 4

Field Value

int

PitchDistanceLodEnabled

public bool PitchDistanceLodEnabled

Field Value

bool

PrefetchParentTiles

public bool PrefetchParentTiles

Field Value

bool

UploadBudgetMs

public double UploadBudgetMs

Field Value

double

Verbose

public bool Verbose

Field Value

bool

ZoomBlendEnabled

public bool ZoomBlendEnabled

Field Value

bool

ZoomHysteresisSeconds

public double ZoomHysteresisSeconds

Field Value

double

Properties

CacheStats

public TileCacheStats CacheStats { get; }

Property Value

TileCacheStats

CapacityLevelDrops

public int CapacityLevelDrops { get; }

Property Value

int

Cover

public TileCoverBuilder Cover { get; }

Property Value

TileCoverBuilder

CoverDroppedCount

public int CoverDroppedCount { get; }

Property Value

int

CoverExactCount

public int CoverExactCount { get; }

Property Value

int

CoverFallbackCount

public int CoverFallbackCount { get; }

Property Value

int

CoverPinTruncatedCount

public int CoverPinTruncatedCount { get; }

Property Value

int

CoverRefPinDroppedCount

public int CoverRefPinDroppedCount { get; }

Property Value

int

CoverUncoveredCount

public int CoverUncoveredCount { get; }

Property Value

int

DecodeDroppedCount

public int DecodeDroppedCount { get; }

Property Value

int

DecodeOffloadAllowed

public bool DecodeOffloadAllowed { get; }

Property Value

bool

DecodeQueueCount

public int DecodeQueueCount { get; }

Property Value

int

DecodeRejectedCount

public int DecodeRejectedCount { get; }

Property Value

int

DecodeStaleDiscardCount

public int DecodeStaleDiscardCount { get; }

Property Value

int

DecodeWorkerFallbackCount

public int DecodeWorkerFallbackCount { get; }

Property Value

int

DecodeWorkerOffloadedCount

public int DecodeWorkerOffloadedCount { get; }

Property Value

int

DecodedTileCount

public int DecodedTileCount { get; }

Property Value

int

DiskCacheCompactionsRun

public int DiskCacheCompactionsRun { get; }

Property Value

int

DiskCacheDirectory

public string DiskCacheDirectory { get; }

Property Value

string

DiskCacheDisabled

public bool DiskCacheDisabled { get; }

Property Value

bool

DiskCacheDroppedWrites

public int DiskCacheDroppedWrites { get; }

Property Value

int

DiskCacheIoFailures

public int DiskCacheIoFailures { get; }

Property Value

int

DiskCacheMaxBytes

public long DiskCacheMaxBytes { get; }

Property Value

long

DiskCacheShrinking

public bool DiskCacheShrinking { get; }

Property Value

bool

DiskHitCount

public int DiskHitCount { get; }

Property Value

int

DrainedResultCount

public int DrainedResultCount { get; }

Property Value

int

DroppedDequeueCount

public int DroppedDequeueCount { get; }

Property Value

int

EvictedCount

public int EvictedCount { get; }

Property Value

int

Fades

public FadeTracker Fades { get; }

Property Value

FadeTracker

FailedCount

public int FailedCount { get; }

Property Value

int

FloorMaxZoom

public int FloorMaxZoom { get; }

Property Value

int

FloorPinDroppedCount

public int FloorPinDroppedCount { get; }

Property Value

int

FloorPinEnabled

public bool FloorPinEnabled { get; set; }

Property Value

bool

FloorPinKeyCount

public int FloorPinKeyCount { get; }

Property Value

int

FloorPinMaxZoom

public int FloorPinMaxZoom { get; }

Property Value

int

FloorPrefetchCachedCount

public int FloorPrefetchCachedCount { get; }

Property Value

int

FloorPrefetchEligible

public bool FloorPrefetchEligible { get; }

Property Value

bool

FloorPrefetchEnabled

public bool FloorPrefetchEnabled { get; set; }

Property Value

bool

FloorPrefetchRemaining

public int FloorPrefetchRemaining { get; }

Property Value

int

FloorPrefetchTotal

public int FloorPrefetchTotal { get; }

Property Value

int

FootprintPinDroppedCount

public int FootprintPinDroppedCount { get; }

Property Value

int

GrowCompletedCount

public int GrowCompletedCount { get; }

Property Value

int

GrowInFlight

public bool GrowInFlight { get; }

Property Value

bool

HysteresisDroppedCount

public int HysteresisDroppedCount { get; }

Property Value

int

InFlightCount

public int InFlightCount { get; }

Property Value

int

IsBusy

public bool IsBusy { get; }

Property Value

bool

LastDecodeMs

public double LastDecodeMs { get; }

Property Value

double

LastGrowCopyMs

public double LastGrowCopyMs { get; }

Property Value

double

LastUncappedFootprint

public int LastUncappedFootprint { get; }

Property Value

int

LastUploadMs

public double LastUploadMs { get; }

Property Value

double

LayerCapacity

public int LayerCapacity { get; }

Property Value

int

MaxStagingCopyMs

public double MaxStagingCopyMs { get; }

Property Value

double

MigrationCount

public int MigrationCount { get; }

Property Value

int

NetworkStartedCount

public int NetworkStartedCount { get; }

Property Value

int

PendingFailureCount

public int PendingFailureCount { get; }

Property Value

int

PendingLayerCapacity

public int PendingLayerCapacity { get; }

Property Value

int

PendingTransientFailureCount

public int PendingTransientFailureCount { get; }

Property Value

int

PermanentFailCount

public int PermanentFailCount { get; }

Property Value

int

PinBudget

public int PinBudget { get; }

Property Value

int

PinnedInsertFailures

public int PinnedInsertFailures { get; }

Property Value

int

PinnedKeyCount

public int PinnedKeyCount { get; }

Property Value

int

PrefetchFailStreak

public int PrefetchFailStreak { get; }

Property Value

int

PrefetchFloorInFlightCount

public int PrefetchFloorInFlightCount { get; }

Property Value

int

PrefetchInFlightCount

public int PrefetchInFlightCount { get; }

Property Value

int

QueuedForDecodeCount

public int QueuedForDecodeCount { get; }

Property Value

int

RegionFailStreak

public int RegionFailStreak { get; }

Property Value

int

RegionPrefetchRemaining

public int RegionPrefetchRemaining { get; }

Property Value

int

RegionPrefetchTotal

public int RegionPrefetchTotal { get; }

Property Value

int

ResidentLayerCount

public int ResidentLayerCount { get; }

Property Value

int

ResidentServedCount

public int ResidentServedCount { get; }

Property Value

int

RetainDroppedCount

public int RetainDroppedCount { get; }

Property Value

int

SelectionDownstreamSkipCount

public int SelectionDownstreamSkipCount { get; }

Property Value

int

SelectionLevel

public int SelectionLevel { get; }

Property Value

int

SelectionSweepCount

public int SelectionSweepCount { get; }

Property Value

int

StalledSlotReclaimedCount

public int StalledSlotReclaimedCount { get; }

Property Value

int

TileFadeSeconds

public double TileFadeSeconds { get; set; }

Property Value

double

TotalDecodeMs

public double TotalDecodeMs { get; }

Property Value

double

TotalUploadMs

public double TotalUploadMs { get; }

Property Value

double

UploadRollbackCount

public int UploadRollbackCount { get; }

Property Value

int

UploadedCount

public int UploadedCount { get; }

Property Value

int

VisibleCount

public int VisibleCount { get; }

Property Value

int

WebBlockEncodeFailed

public bool WebBlockEncodeFailed { get; }

Property Value

bool

WebDecodeOffloadedCount

public int WebDecodeOffloadedCount { get; }

Property Value

int

WebGpuDirectUploadActive

public bool WebGpuDirectUploadActive { get; }

Property Value

bool

WebGpuDirectUploadedCount

public int WebGpuDirectUploadedCount { get; }

Property Value

int

WebWorkerDecodeActive

public bool WebWorkerDecodeActive { get; }

Property Value

bool

WindowDiskHitCount

public int WindowDiskHitCount { get; }

Property Value

int

WindowDownloadedCount

public int WindowDownloadedCount { get; }

Property Value

int

WindowFailedCount

public int WindowFailedCount { get; }

Property Value

int

WindowResidentServedCount

public int WindowResidentServedCount { get; }

Property Value

int

ZoomLevelHysteresis

public double ZoomLevelHysteresis { get; set; }

Property Value

double

Methods

ClearDiskCache()

Wipes the packed disk files; GPU residency is unchanged.

public void ClearDiskCache()

CompactDiskCacheNow()

Rewrites the packed file now to reclaim orphaned blobs, and returns true if the file shrank.

public bool CompactDiskCacheNow()

Returns

bool

DetachDiskStore()

Releases this streamer's hold on its disk store, for a pool that is about to park this streamer rather than dispose it.

public void DetachDiskStore()

Remarks

A parked streamer that keeps holding tiles.dat/tiles.idx (FileShare.None) blocks any other streamer built for the same cache directory from ever opening it - the disk cache dies for the rest of the session instead of just this one streamer's idle stretch. This disposes the real store (which flushes before closing), swaps in a degraded one (misses and drops, like any other open failure), and re-arms the same reopen retry TryAttachDiskStore already runs, restarting its backoff from now. A later Checkout (Tick(MapViewTransform, double) via the pending reopen flag) reattaches a real store without anyone else having to have released one first.

Dispose()

Releases the fetcher, disk store, decode worker, and staging textures.

public void Dispose()

FloorStallSeconds(double)

Seconds until the idle world-floor trickle resumes; 0 when it is not stalled.

public double FloorStallSeconds(double now)

Parameters

now double

Current time in seconds (realtimeSinceStartupAsDouble).

Returns

double

GrowCapacity(int)

Grows the GPU tile array and residency cache toward a larger layer count; never shrinks.

public void GrowCapacity(int newLayerCount)

Parameters

newLayerCount int

Target layer count; must be greater than the current capacity.

Remarks

Throws if the renderer and cache capacities already disagree, or if newLayerCount is not greater than the current capacity. A grow already in flight coalesces to the larger target. Call from the main thread between Ticks.

HysteresisActiveCount(double)

How many previous-zoom keys are still inside their pin window.

public int HysteresisActiveCount(double now)

Parameters

now double

Current time in seconds (realtimeSinceStartupAsDouble).

Returns

int

PeekPinned(long)

True when the packed key is GPU-resident and currently pinned; does not reorder eviction.

public bool PeekPinned(long key)

Parameters

key long

Packed tile key.

Returns

bool

PeekResident(long)

True when the packed key is GPU-resident; does not reorder eviction.

public bool PeekResident(long key)

Parameters

key long

Packed tile key.

Returns

bool

PrefetchStallSeconds(double)

Seconds until parent prefetch resumes; 0 when it is not stalled.

public double PrefetchStallSeconds(double now)

Parameters

now double

Current time in seconds (realtimeSinceStartupAsDouble).

Returns

double

RegionStallSeconds(double)

Seconds until bulk region prefetch resumes; 0 when it is not stalled.

public double RegionStallSeconds(double now)

Parameters

now double

Current time in seconds (realtimeSinceStartupAsDouble).

Returns

double

ResidentVisibleCount()

Count of currently selected tiles that are GPU-resident, without changing eviction order.

public int ResidentVisibleCount()

Returns

int

ResolveFetcherSlotCount(ITileDataSource)

Transport slots to construct this source's fetcher with, folding in its PrefetchReserveSlots additively unless the source's concurrency was already lowered for provider politeness.

public static int ResolveFetcherSlotCount(ITileDataSource source)

Parameters

source ITileDataSource

The tile source the fetcher will serve.

Returns

int

RunSelectionPassForTest(MapViewTransform, double)

public void RunSelectionPassForTest(MapViewTransform view, double now)

Parameters

view MapViewTransform
now double

SetDiskCacheMaxBytes(long)

Changes the live disk cap in bytes; growth is immediate, shrink evicts across following ticks.

public void SetDiskCacheMaxBytes(long maxDataBytes)

Parameters

maxDataBytes long

New live-data cap in bytes.

SetPanVelocityTilesPerSecond(double, double)

Sets predicted pan velocity used to prioritize in-view fetches.

public void SetPanVelocityTilesPerSecond(double vx, double vy)

Parameters

vx double

Pan velocity X in tiles per second at the selection level.

vy double

Pan velocity Y in tiles per second at the selection level.

StartRegionPrefetch(GeoBounds, int, int, int)

Queues the bounds/zoom range for idle disk-only download, returning false instead of starting when the tile count exceeds maxTiles.

public bool StartRegionPrefetch(GeoBounds bounds, int minZoom, int maxZoom, int maxTiles = 20000)

Parameters

bounds GeoBounds

Geographic extent to cache.

minZoom int

Inclusive coarsest zoom in Web Mercator zoom units.

maxZoom int

Inclusive finest zoom in Web Mercator zoom units.

maxTiles int

Hard cap on queued tiles; exceeding it returns false and queues nothing.

Returns

bool

True when the job was queued.

Tick(MapViewTransform, double)

Advances selection, fetch, pin, budgeted decode/upload, and cover for one frame.

public void Tick(MapViewTransform view, double now)

Parameters

view MapViewTransform

Current map view.

now double

Current time in seconds (realtimeSinceStartupAsDouble).

TryGetLayer(long, out int)

Looks up the packed key and marks it most-recently used.

public bool TryGetLayer(long key, out int layer)

Parameters

key long

Packed tile key.

layer int

Layer index on success.

Returns

bool

True when the key is GPU-resident.

TryReattachDiskStoreNow()

Attempts to reopen the real disk store right now, without waiting for the scheduled reopen backoff. Call on every Checkout.

public void TryReattachDiskStoreNow()

Remarks

The scheduled retry (DiskReopenDelaysSeconds, starting at 1 s) exists for a genuine external collision - another process, or another live streamer, still holding the file - where waiting is the only option. A pooled streamer coming back out of a Checkout is usually not that case: DetachDiskStore() already released this exact streamer's own hold on the file when it was parked, so nothing else is actually contending for it, and a reused streamer paying the first 1 s delay on every single reuse - the common path pooling exists for - would silently drop every disk write and disk hit during that window for no real reason. This call does not count against the three-attempt budget and does not touch the scheduled retry's own state: on failure (a real collision after all), TryAttachDiskStore(double) still runs on its normal schedule from the next Tick(MapViewTransform, double), exactly as if this call had not happened.

VisibleContainsTile(TileCoord)

public bool VisibleContainsTile(TileCoord tile)

Parameters

tile TileCoord

Returns

bool