Package icyllis.arc3d.engine

# Class Resource

java.lang.Object
icyllis.arc3d.engine.Resource

All Implemented Interfaces:
  `RefCounted`

Direct Known Subclasses:
  `Buffer`, `GpuSurface`, `Image`, `Sampler`

@NotThreadSafe public abstract class Resource extends Object implements RefCounted
Base class for operating GPU resources that can be kept in the `ResourceCache`.

Resources that have memory allocation:

- GLBuffer
- GLTexture
- GLRenderbuffer
- VulkanBuffer
- VulkanImage

Resources that are zero-sized:

- GLSampler
- VulkanSampler
- VulkanRenderPass

Register resources into the cache to track their GPU memory usage. Since all Java objects will always be strong referenced, an explicit `ref()` and `unref()` is required to determine if they need to be recycled or not. When used as smart pointers, they need to be annotated as `SharedPtr`, otherwise they tend to be used as raw pointers (no ref/unref calls should be made). A paired `UniqueID` object can be used as unique identifiers.

Each `Resource` should be created with immutable GPU memory allocation. `Resource` can be only created/operated on the creating thread of `getContext()`, but may be recycled from other threads. Use `ResourceProvider` to obtain `Resource` objects.

- ## Constructor Summary

  Constructors
  Modifier
  Constructor
  Description
  `protected`
  `Resource(Context context, boolean budgeted, boolean wrapped, long memorySize)`

- ## Method Summary

  Modifier and Type
  Method
  Description
  `final Context`
  `getContext()`
  Retrieves the context that owns the object.
  `protected Device`
  `getDevice()`
  `final IResourceKey`
  `getKey()`
  If this resource can be used as a scratch resource this returns a valid scratch key.
  `final String`
  `getLabel()`
  `final long`
  `getMemorySize()`
  Retrieves the amount of GPU memory used by this resource in bytes.
  `UniqueID`
  `getUniqueID()`
  Gets a tag that is unique for this Resource object.
  `final boolean`
  `hasAnyRefs()`
  `protected final boolean`
  `hasCacheRef()`
  `protected final boolean`
  `hasCommandBufferRef()`
  `protected final boolean`
  `hasUsageRef()`
  `final boolean`
  `isBudgeted()`
  Get the resource's budget type which indicates whether it counts against the resource cache budget.
  `final boolean`
  `isDestroyed()`
  Checks whether an object has been released or discarded.
  `final boolean`
  `isPurgeable()`
  `final boolean`
  `isWrapped()`
  Is the resource object wrapping an externally allocated GPU resource?
  `protected abstract void`
  `onRelease()`
  Subclass should override this method to free GPU resources in the backend API.
  `protected void`
  `onSetLabel(String label)`
  Subclass should override this method to set object label in the backend API.
  `final void`
  `ref()`
  Increases the reference count by 1 on the client pipeline.
  `final void`
  `refCommandBuffer()`
  Increases the usage count by 1 on the tracked backend pipeline.
  `final void`
  `setKey(IResourceKey key)`
  Called before registerWithCache if the resource is available to be used as scratch.
  `final void`
  `setLabel(String label)`
  Sets a label for the resource for debugging purposes, the label must contain only ASCII characters.
  `protected final void`
  `setNonCacheable()`
  `final void`
  `unref()`
  Decreases the reference count by 1 on the client pipeline.
  `final void`
  `unrefCommandBuffer()`
  Decreases the usage count by 1 on the tracked backend pipeline.

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

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

- ## Constructor Details

  - ### Resource

    protected Resource(Context context, boolean budgeted, boolean wrapped, long memorySize)

- ## Method Details

  - ### ref

    public final void ref()
    Increases the reference count by 1 on the client pipeline. It's an error to call this method if the reference count has already reached zero.
    Specified by:
      `ref` in interface `RefCounted`

  - ### unref

    public final void unref()
    Decreases the reference count by 1 on the client pipeline. It's an error to call this method if the reference count has already reached zero.
    Specified by:
      `unref` in interface `RefCounted`

  - ### refCommandBuffer

    public final void refCommandBuffer()
    Increases the usage count by 1 on the tracked backend pipeline.

    This is designed to be used by Resources that need to track when they are in use on backend (usually via a command buffer) separately from tracking if there are any current logical usages in client. This allows for a scratch Resource to be reused for new draw calls even if it is in use on the backend.

  - ### unrefCommandBuffer

    public final void unrefCommandBuffer()
    Decreases the usage count by 1 on the tracked backend pipeline. It's an error to call this method if the usage count has already reached zero.

  - ### hasUsageRef

    protected final boolean hasUsageRef()

  - ### hasCommandBufferRef

    protected final boolean hasCommandBufferRef()

  - ### hasCacheRef

    protected final boolean hasCacheRef()

  - ### isDestroyed

    public final boolean isDestroyed()
    Checks whether an object has been released or discarded. All objects will be in this state after their creating Context is destroyed or has contextLost called. It's up to the client to test isDestroyed() before attempting to use an object if it holds refs on objects across Context.close(), freeResources with the force flag, or contextLost.
    Returns:
      true if the object has been released or discarded, false otherwise.

  - ### getContext

    @Nullable public final Context getContext()
    Retrieves the context that owns the object. Note that it is possible for this to return null. When objects have been release()ed or discard()ed they no longer have an owning context. Destroying a `Context` automatically releases all its resources.

  - ### getMemorySize

    public final long getMemorySize()
    Retrieves the amount of GPU memory used by this resource in bytes. It is approximate since we aren't aware of additional padding or copies made by the driver.
    Returns:
      the amount of GPU memory used in bytes

  - ### isBudgeted

    public final boolean isBudgeted()
    Get the resource's budget type which indicates whether it counts against the resource cache budget.

  - ### getUniqueID

    @Nonnull public UniqueID getUniqueID()
    Gets a tag that is unique for this Resource object. It is static in that it does not change when the content of the Resource object changes. It has identity and never hold a reference to this Resource object, so it can be used to track state changes through '=='.

  - ### getLabel

    @Nonnull public final String getLabel()
    Returns:
      the label for the resource, or empty

  - ### setLabel

    public final void setLabel(@Nullable String label)
    Sets a label for the resource for debugging purposes, the label must contain only ASCII characters.
    Parameters:
      `label` - the new label to set, null or empty to clear

  - ### isWrapped

    @Internal public final boolean isWrapped()
    Is the resource object wrapping an externally allocated GPU resource?

  - ### getKey

    @Internal public final IResourceKey getKey()
    If this resource can be used as a scratch resource this returns a valid scratch key. Otherwise, it returns a key for which isNullScratch is true. The resource may currently be used as a uniquely keyed resource rather than scratch. Check isScratch().

  - ### setKey

    @Internal public final void setKey(@Nonnull IResourceKey key)
    Called before registerWithCache if the resource is available to be used as scratch. Resource subclasses should override this if the instances should be recycled as scratch resources and populate the scratchKey with the key. By default, resources are not recycled as scratch.

  - ### isPurgeable

    @Internal public final boolean isPurgeable()

  - ### hasAnyRefs

    @Internal public final boolean hasAnyRefs()

  - ### setNonCacheable

    protected final void setNonCacheable()

  - ### getDevice

    protected Device getDevice()
    Returns:
      the device or null if destroyed

  - ### onRelease

    protected abstract void onRelease()
    Subclass should override this method to free GPU resources in the backend API.

  - ### onSetLabel

    protected void onSetLabel(@Nullable String label)
    Subclass should override this method to set object label in the backend API.