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 Details

  • 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.