Skip to content

Colossal.Rendering.VTTextureRequester

Assembly: Assembly-CSharp (game)
Namespace: Colossal.Rendering

Type: class

Base: System.IDisposable

Summary:
VTTextureRequester collects and manages requests for virtual texture (VT) regions and forwards those requests to the TextureStreamingSystem when they meet a pixel-size threshold. It stores per-"stack" lists of registered VT indices, their stack-global indices, bounds, and the maximum requested pixels observed for each registration. Designed for Cities: Skylines 2 texture streaming/modding, it uses Unity.Collections.NativeList for low-level allocation and must be disposed to avoid leaks.


Fields

  • private NativeList<int>[] m_TexturesIndices
    Holds arrays (per stack config) of VT indices for registered textures. Each element is a NativeList of vtIndex integers. Allocated with Allocator.Persistent in the constructor.

  • private NativeList<int>[] m_StackGlobalIndices
    Parallel arrays to m_TexturesIndices storing the stack-global index for each registered texture entry. Used when issuing requests to the TextureStreamingSystem.

  • private NativeList<Bounds2>[] m_TextureBounds
    Parallel arrays storing Bounds2 for each registered texture entry. Bounds2 is from Colossal.Mathematics and represents the VT region to request.

  • private NativeList<float>[] m_TexturesMaxPixels
    Parallel arrays storing the maximum pixel size observed for each registered texture entry. Used to decide whether to request higher-resolution VT regions.

  • private TextureStreamingSystem m_TextureStreamingSystem
    Reference to the game's TextureStreamingSystem instance used to actually issue VT region requests.

  • private int m_RequestedThisFrame
    Counter for how many VT requests were issued during the last UpdateTexturesVTRequests() call.

Properties

  • public int stacksCount => m_TexturesIndices.Length
    Returns number of stacks (the length of the internal arrays). In the current implementation this is 2.

  • public int registeredCount
    Returns the total number of registered texture entries across all stacks by summing the lengths of the per-stack NativeList arrays.

  • public int requestCount => m_RequestedThisFrame
    Number of VT region requests issued during the last call to UpdateTexturesVTRequests().

  • public NativeList<float>[] TexturesMaxPixels => m_TexturesMaxPixels
    Exposes the internal per-stack NativeList arrays of max pixel values so callers can inspect or modify them if necessary (use with care — these are NativeList instances).

Constructors

  • public VTTextureRequester(TextureStreamingSystem textureStreamingSystem)
    Creates a VTTextureRequester and allocates all internal NativeList arrays (2 stacks, each initial capacity 100, Allocator.Persistent). Stores the TextureStreamingSystem reference. Because NativeList uses native memory, Dispose must be called when the requester is no longer needed.

Methods

  • public void Dispose()
    Disposes all internal NativeList instances to free native memory. Must be called to avoid leaks. It iterates over each internal array and calls Dispose().

  • public void Clear()
    Clears (but does not dispose) all internal NativeList contents. Keeps capacity and native allocations intact.

  • public void UpdateTexturesVTRequests()
    Evaluates stored max-pixel values for all registered entries and requests VT regions from the TextureStreamingSystem when conditions are met. Behavior details:

  • Resets m_RequestedThisFrame to 0 at start.
  • Applies a working set LOD bias: if textureStreamingSystem.workingSetLodBias > 1, the maxPixel values are scaled down by 1 / workingSetLodBias.
  • For each registered texture entry, computes scaled max pixel size and if it is greater than 4.0, calls m_TextureStreamingSystem.RequestRegion(stackGlobalIndex, vtIndex, pixels, bounds), sets that entry's stored max pixel to -1, and increments the requested counter.
  • The threshold (4 pixels) and the bias handling are important to understand when tuning streaming behavior.

  • public int RegisterTexture(int stackConfigIndex, int stackGlobalIndex, int vtIndex, Bounds2 bounds)
    Registers a texture entry for future VT requests:

  • If an identical entry (same vtIndex, stackGlobalIndex, and bounds) already exists in the specified stackConfigIndex, returns its index.
  • Otherwise adds vtIndex, stackGlobalIndex, bounds and an initial max-pixel value (-1f), then returns the new entry index.
  • Note: uses NativeList.Add(in value) overloads to avoid copies.

  • public int GetTextureIndex(int stackIndex, int texturesIndex)
    Returns the stored vtIndex for the given stackIndex and texturesIndex (i.e., m_TexturesIndices[stackIndex][texturesIndex]).

  • public void UpdateMaxPixel(int stackIndex, int texturesIndex, float maxPixel)
    Updates the stored maximum pixel size for a registered entry by taking the max of the current stored value and the supplied value (Mathf.Max). Used by producers that measure desired resolution per frame.

Usage Example

// Example usage inside a mod component
public class MyVTUser : MonoBehaviour
{
    private VTTextureRequester _vtRequester;
    private TextureStreamingSystem _streamingSystem; // obtain from game context

    void Start()
    {
        _streamingSystem = /* get TextureStreamingSystem instance from game */;
        _vtRequester = new VTTextureRequester(_streamingSystem);
    }

    void OnDestroy()
    {
        // Important: release native memory
        _vtRequester.Dispose();
    }

    void Update()
    {
        // Register a texture (only once ideally). stackConfigIndex is 0 or 1 in this implementation.
        Bounds2 bounds = new Bounds2(new float2(0,0), new float2(1,1));
        int entryIndex = _vtRequester.RegisterTexture(0, stackGlobalIndex: 123, vtIndex: 5, bounds: bounds);

        // Each frame, update observed max pixel for that entry
        _vtRequester.UpdateMaxPixel(0, entryIndex, computedMaxPixel);

        // Periodically (once per frame in this implementation) request regions if thresholds are met
        _vtRequester.UpdateTexturesVTRequests();

        // You can inspect how many requests were issued:
        int requests = _vtRequester.requestCount;
    }
}

Notes and modding tips: - NativeList allocations use Allocator.Persistent: always call Dispose when the requester is no longer used (usually in OnDestroy) to prevent leaks and crashes. - The class currently initializes two stacks (arrays of length 2). If the game changes that number, this class must be updated accordingly. - The threshold for issuing a request is hard-coded to > 4 pixels after LOD-bias scaling. Adjust the logic where appropriate if you need different behavior. - Bounds2, TextureStreamingSystem and RequestRegion are internal/game types — ensure your mod has correct access (reflection or proper API) before calling them.