Dala.Gpu.Surface (dala v0.3.2)

Copy Markdown View Source

GenServer that holds the state for a GPU surface.

Each surface corresponds to a Rust-side GPU renderer with a CPU-side framebuffer, a command queue, and a GPU texture. The GenServer owns the NIF reference and ensures clean teardown via terminate/2.

Commands are fire-and-forget (cast) for performance. Pixel access is synchronous (call) since it returns data.

Summary

Functions

Execute a batch of pre-encoded commands.

Blit a loaded sprite at the given position.

Returns a specification to start this module under a supervisor.

Clear the surface with a solid color.

Draw a loaded image onto the framebuffer.

Draw a line between two points.

Draw a rounded rectangle outline.

Fill a rectangle with a solid color.

Get surface info as a map.

Read the current pixel data as an RGBA8888 binary.

Load an image into the GPU texture pool.

Load or hot-reload a shader.

Load a sprite into the texture atlas for later blitting.

Present the surface — flush the command queue and update the GPU texture.

Remove an image from the GPU texture pool.

Remove a sprite from the texture atlas.

Reset the clipping region.

Resize the surface.

Set the clipping rectangle.

Set the pixel data directly. Binary must be exactly width height 4 bytes.

Set a uniform value.

Start a linked surface GenServer.

Stop the surface GenServer and free GPU resources.

Check compute support.

Modify pixels via a callback. The callback receives the current RGBA8888 binary and must return the new RGBA8888 binary of the same size.

Types

t()

@type t() :: %Dala.Gpu.Surface{
  height: non_neg_integer(),
  ref: reference(),
  width: non_neg_integer()
}

Functions

batch(pid, commands)

@spec batch(pid(), [binary()]) :: :ok

Execute a batch of pre-encoded commands.

blit(pid, sprite_id, x, y)

@spec blit(pid(), non_neg_integer(), integer(), integer()) :: :ok

Blit a loaded sprite at the given position.

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

clear(pid, color)

@spec clear(pid(), Dala.Gpu.Command.color()) :: :ok

Clear the surface with a solid color.

dispatch_compute(pid, shader_source, params, workgroup_count)

@spec dispatch_compute(
  pid(),
  String.t(),
  binary(),
  {non_neg_integer(), non_neg_integer(), non_neg_integer()}
) :: :ok | {:error, term()}

Dispatch a GPU compute shader.

draw_circle(pid, cx, cy, radius, color)

@spec draw_circle(
  pid(),
  integer(),
  integer(),
  non_neg_integer(),
  Dala.Gpu.Command.color()
) :: :ok

Draw a circle outline.

draw_image(pid, image_id, x, y, w, h)

@spec draw_image(
  pid(),
  non_neg_integer(),
  integer(),
  integer(),
  non_neg_integer(),
  non_neg_integer()
) ::
  :ok

Draw a loaded image onto the framebuffer.

draw_line(pid, x1, y1, x2, y2, color)

@spec draw_line(
  pid(),
  integer(),
  integer(),
  integer(),
  integer(),
  Dala.Gpu.Command.color()
) :: :ok

Draw a line between two points.

draw_round_rect(pid, x, y, w, h, radius, color)

Draw a rounded rectangle outline.

draw_triangle(pid, x1, y1, x2, y2, x3, y3, color)

@spec draw_triangle(
  pid(),
  integer(),
  integer(),
  integer(),
  integer(),
  integer(),
  integer(),
  Dala.Gpu.Command.color()
) :: :ok

Draw a triangle outline.

fill_circle(pid, cx, cy, radius, color)

@spec fill_circle(
  pid(),
  integer(),
  integer(),
  non_neg_integer(),
  Dala.Gpu.Command.color()
) :: :ok

Fill a circle.

fill_rect(pid, x, y, w, h, color)

Fill a rectangle with a solid color.

fill_round_rect(pid, x, y, w, h, radius, color)

Fill a rounded rectangle.

fill_triangle(pid, x1, y1, x2, y2, x3, y3, color)

@spec fill_triangle(
  pid(),
  integer(),
  integer(),
  integer(),
  integer(),
  integer(),
  integer(),
  Dala.Gpu.Command.color()
) :: :ok

Fill a triangle.

get_info(pid)

@spec get_info(pid()) :: %{width: non_neg_integer(), height: non_neg_integer()}

Get surface info as a map.

get_pixels(pid)

@spec get_pixels(pid()) :: binary()

Read the current pixel data as an RGBA8888 binary.

load_image(pid, id, rgba_binary, width, height)

@spec load_image(
  pid(),
  non_neg_integer(),
  binary(),
  non_neg_integer(),
  non_neg_integer()
) :: :ok

Load an image into the GPU texture pool.

load_shader(pid, name, source)

@spec load_shader(pid(), String.t(), String.t()) :: :ok | {:error, term()}

Load or hot-reload a shader.

load_sprite(pid, id, rgba_binary, width, height)

@spec load_sprite(
  pid(),
  non_neg_integer(),
  binary(),
  non_neg_integer(),
  non_neg_integer()
) :: :ok

Load a sprite into the texture atlas for later blitting.

present(pid)

@spec present(pid()) :: :ok

Present the surface — flush the command queue and update the GPU texture.

remove_image(pid, id)

@spec remove_image(pid(), non_neg_integer()) :: :ok

Remove an image from the GPU texture pool.

remove_sprite(pid, id)

@spec remove_sprite(pid(), non_neg_integer()) :: :ok

Remove a sprite from the texture atlas.

reset_clip(pid)

@spec reset_clip(pid()) :: :ok

Reset the clipping region.

resize(pid, width, height)

@spec resize(pid(), non_neg_integer(), non_neg_integer()) :: :ok

Resize the surface.

set_clip(pid, x, y, w, h, enabled)

@spec set_clip(
  pid(),
  non_neg_integer(),
  non_neg_integer(),
  non_neg_integer(),
  non_neg_integer(),
  boolean()
) :: :ok

Set the clipping rectangle.

set_pixels(pid, rgba_binary)

@spec set_pixels(pid(), binary()) :: :ok

Set the pixel data directly. Binary must be exactly width height 4 bytes.

set_uniform(pid, name, data)

@spec set_uniform(pid(), String.t(), binary()) :: :ok | {:error, term()}

Set a uniform value.

start_link(opts)

@spec start_link(keyword()) :: GenServer.on_start()

Start a linked surface GenServer.

stop(pid)

@spec stop(pid()) :: :ok

Stop the surface GenServer and free GPU resources.

supports_compute(pid)

@spec supports_compute(pid()) :: boolean()

Check compute support.

with_pixels(pid, fun)

@spec with_pixels(pid(), (binary() -> binary())) :: :ok

Modify pixels via a callback. The callback receives the current RGBA8888 binary and must return the new RGBA8888 binary of the same size.