Package icyllis.arc3d.engine

# Class SurfaceAllocator

java.lang.Object
icyllis.arc3d.engine.SurfaceAllocator

public final class SurfaceAllocator extends Object
The `SurfaceAllocator` explicitly distributes `GpuSurface` at flush time. It operates by being given the usage intervals of the various `SurfaceProxy`. It keeps these intervals in a singly linked list sorted by increasing start index. (It also maintains a hash table from ID to interval to find surface reuse). The ResourceAllocator uses Registers (in the sense of register allocation) to represent a future resource that will be used for each surface during `simulate()`, and then assigns actual resources during `allocate()`.

Note: the op indices (used in the usage intervals) come from the order of the ops in their opsTasks after the opsTask DAG has been linearized.

The `simulate()` method traverses the sorted list and:

- moves intervals from the active list that have completed (returning their registers to the free pool) into the finished list (sorted by increasing start)
- allocates a new register (preferably from the free pool) for the new interval adds the new interval to the active list (that is sorted by increasing end index)

If the user wants to commit to the current simulation, they call `allocate()` which:

- instantiates lazy textures
- instantiates new surfaces for all registers that need them
- assigns the surface for each register to all the proxies that will use it

************************************************************************************************ How does instantiation failure handling work when explicitly allocating?

In the gather usage intervals pass all the SurfaceProxies used in the flush should be gathered (i.e., in `RenderTask.gatherSurfaceIntervals(SurfaceAllocator)`).

During addInterval, read-only lazy proxies are instantiated. If that fails, the resource allocator will note the failure and ignore pretty much anything else until `reset`.

During `simulate()`, lazy-most proxies are instantiated so that we can know their size for budgeting purposes. If this fails, return false.

During `allocate()`, lazy proxies are instantiated and new surfaces are created for all other proxies. If any of these fails, return false.

The task manager will drop the flush if any proxies fail to instantiate.

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `SurfaceAllocator(ImmediateContext context)`

- ## Method Summary

  Modifier and Type
  Method
  Description
  `void`
  `addInterval(@RawPtr SurfaceProxy proxy, int start, int end, boolean actualUse)`
  Add a usage interval from `start` to `end` inclusive.
  `boolean`
  `allocate()`
  Instantiate and assign resources to all proxies.
  `int`
  `curOp()`
  `void`
  `incOps()`
  `boolean`
  `isInstantiationFailed()`
  `void`
  `reset()`
  Called after `simulate()` or `allocate()` on the end of flush.
  `boolean`
  `simulate()`
  Generate an internal plan for resource allocation.

  ### Methods inherited from class java.lang.Object

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- ## Constructor Details

  - ### SurfaceAllocator

    public SurfaceAllocator(ImmediateContext context)

- ## Method Details

  - ### curOp

    public int curOp()

  - ### incOps

    public void incOps()

  - ### addInterval

    public void addInterval(@Nonnull @RawPtr @RawPtr SurfaceProxy proxy, int start, int end, boolean actualUse)
    Add a usage interval from `start` to `end` inclusive. This is usually used for render targets. If an existing interval already exists it will be expanded to include the new range.

    ActualUse: Indicates whether a given call to addInterval represents an actual usage of the provided proxy. This is mainly here to accommodate deferred proxies attached to opsTasks. In that case we need to create an extra long interval for them (due to the upload) but don't want to count that usage/reference towards the proxy's recyclability.

    Parameters:
      `proxy` - the raw ptr to the surface proxy
      `start` - the start op
      `end` - the end op

  - ### isInstantiationFailed

    public boolean isInstantiationFailed()

  - ### simulate

    public boolean simulate()
    Generate an internal plan for resource allocation.

    Lazy-most proxies are also instantiated at this point so that their size can be known accurately. Returns false if any lazy proxy failed to instantiate, true otherwise.

  - ### allocate

    public boolean allocate()
    Instantiate and assign resources to all proxies.

  - ### reset

    public void reset()
    Called after `simulate()` or `allocate()` on the end of flush.