libdragon
|
Surface buffers used to draw images. More...
Go to the source code of this file.
Data Structures | |
struct | surface_t |
A surface buffer for graphics. More... | |
Macros | |
#define | TEX_FORMAT_BITDEPTH(fmt) (4 << ((fmt) & 0x3)) |
Extract the depth (number of bits per pixel) from a tex_format_t. (eg: FMT_RGBA16 => 16) | |
#define | TEX_FORMAT_PIX2BYTES(fmt, pixels) ((((pixels) << (((fmt) & 3) + 2)) + 7) >> 3) |
Convert the specified number of pixels to bytes. | |
#define | TEX_FORMAT_BYTES2PIX(fmt, bytes) (((bytes) << 1) >> ((fmt) & 3)) |
Convert the specified number of bytes to pixels. | |
#define | SURFACE_FLAGS_TEXFORMAT 0x001F |
Pixel format of the surface. | |
#define | SURFACE_FLAGS_OWNEDBUFFER 0x0020 |
Set if the buffer must be freed. | |
#define | SURFACE_FLAGS_TEXINDEX 0x0F00 |
Placeholder for rdpq lookup table. | |
Enumerations | |
enum | tex_format_t { FMT_NONE = 0 , FMT_RGBA16 = _RDP_FORMAT_CODE(0, 2) , FMT_RGBA32 = _RDP_FORMAT_CODE(0, 3) , FMT_YUV16 = _RDP_FORMAT_CODE(1, 2) , FMT_CI4 = _RDP_FORMAT_CODE(2, 0) , FMT_CI8 = _RDP_FORMAT_CODE(2, 1) , FMT_IA4 = _RDP_FORMAT_CODE(3, 0) , FMT_IA8 = _RDP_FORMAT_CODE(3, 1) , FMT_IA16 = _RDP_FORMAT_CODE(3, 2) , FMT_I4 = _RDP_FORMAT_CODE(4, 0) , FMT_I8 = _RDP_FORMAT_CODE(4, 1) } |
Pixel format enum. More... | |
Functions | |
const char * | tex_format_name (tex_format_t fmt) |
Return the name of the texture format as a string (for debugging purposes) | |
surface_t | surface_make (void *buffer, tex_format_t format, uint16_t width, uint16_t height, uint16_t stride) |
Initialize a surface_t structure with the provided buffer. | |
surface_t | surface_make_linear (void *buffer, tex_format_t format, uint16_t width, uint16_t height) |
Initialize a surface_t structure with the provided linear buffer. | |
surface_t | surface_alloc (tex_format_t format, uint16_t width, uint16_t height) |
Allocate a new surface in memory. | |
surface_t | surface_make_sub (surface_t *parent, uint16_t x0, uint16_t y0, uint16_t width, uint16_t height) |
Initialize a surface_t structure, pointing to a rectangular portion of another surface. | |
void | surface_free (surface_t *surface) |
Free the buffer allocated in a surface. | |
tex_format_t | surface_get_format (const surface_t *surface) |
Returns the pixel format of a surface. | |
bool | surface_has_owned_buffer (const surface_t *surface) |
Checks whether this surface owns the buffer that it contains. | |
surface_t | surface_make_placeholder (int index, tex_format_t format, uint16_t width, uint16_t height, uint16_t stride) |
Create a placeholder surface, that can be used during rdpq block recording. | |
surface_t | surface_make_placeholder_linear (int index, tex_format_t format, uint16_t width, uint16_t height) |
Create a linear placeholder surface, that can be used during rdpq block recording. | |
int | surface_get_placeholder_index (const surface_t *surface) |
Returns the lookup index of a placeholder surface. | |
Surface buffers used to draw images.
This module implements a structure surface_t which holds the basic information for a buffer of memory to be used for graphics rendering.
A surface is described by the following properties:
surface_t simply represents an aggregation of these properties.
To allocate a new surface, use surface_alloc. Then later, you can release the memory using surface_free.
Sometimes, you might have an existing raw pointer to a buffer and need to pass it to an API that accepts a surface_t. For those cases, you can use surface_make to create a surface_t instance, that you can throw away after you called the function; surface_free does nothing on these surfaces.
In some cases, you might want to interact with a rectangular portion of an existing surface (for instance, you want to draw with RDP only in the top portion of the screen for some reason). To do so, you can use surface_make_sub to create a surface_t instance that is referring only to a portion of the original surface:
Surfaces created by surface_make_sub don't need to be freed as they are just references to the parent surface; surface_free does nothing on them.
struct surface_t |
A surface buffer for graphics.
This structure holds the basic information about a buffer used to hold graphics. It is commonly used by graphics routines in libdragon as either a source (eg: texture) or a target (eg: framebuffer). It can be used for both CPU-based drawing (such as graphics.h) or RDP-basic drawing (such as rdp.h and rdpq.h).
Use surface_alloc / surface_free to allocate / free a surface. If you already have a memory pointer to a graphics buffer and you just need to wrap it in a surface_t, use surface_make.
#define TEX_FORMAT_BITDEPTH | ( | fmt | ) | (4 << ((fmt) & 0x3)) |
Extract the depth (number of bits per pixel) from a tex_format_t. (eg: FMT_RGBA16
=> 16)
Note that there are texture format that are 4bpp, so don't divide this by 8 to get the number of bytes per pixels, but rather use TEX_FORMAT_BYTES2PIX and TEX_FORMAT_PIX2BYTES.
#define TEX_FORMAT_PIX2BYTES | ( | fmt, | |
pixels | |||
) | ((((pixels) << (((fmt) & 3) + 2)) + 7) >> 3) |
Convert the specified number of pixels to bytes.
TEX_FORMAT_PIX2BYTES(FMT_CI4, 3)
returns 2, as you need 2 bytes to store 3 pixels in 4bpp format (even though the last byte is only half used). #define TEX_FORMAT_BYTES2PIX | ( | fmt, | |
bytes | |||
) | (((bytes) << 1) >> ((fmt) & 3)) |
Convert the specified number of bytes to pixels.
TEX_FORMAT_BYTES2PIX(FMT_RGBA32, 5)
returns 1, because you can safely store at maximum 1 32bpp pixel in 5 bytes. enum tex_format_t |
Pixel format enum.
This enum defines the pixel formats that can be used for surface_t buffers. The list corresponds to the pixel formats that the RDP can use as textures.
|
inline |
Initialize a surface_t structure with the provided buffer.
This functions initializes a surface_t structure with the provided buffer and information. It is just a helper to fill the structure fields.
It is not necessary to call surface_free on surfaces created by surface_make as there is nothing to free: the provided buffer will not be owned by the structure, so it is up to the caller to handle its lifetime.
If you plan to use this format as RDP framebuffer, make sure that the provided buffer respects the required alignment of 64 bytes, otherwise rdpq_attach will fail.
[in] | buffer | Pointer to the memory buffer |
[in] | format | Pixel format |
[in] | width | Width in pixels |
[in] | height | Height in pixels |
[in] | stride | Stride in bytes (length of a row) |
|
inline |
Initialize a surface_t structure with the provided linear buffer.
This function is similar to surface_make, but it works for images that are linearly mapped with no per-line padding or extraneous data.
Compared to surface_make, it does not accept a stride parameter, and calculate the stride from the width and the pixel format.
[in] | buffer | Pointer to the memory buffer |
[in] | format | Pixel format |
[in] | width | Width in pixels |
[in] | height | Height in pixels |
surface_t surface_alloc | ( | tex_format_t | format, |
uint16_t | width, | ||
uint16_t | height | ||
) |
Allocate a new surface in memory.
This function allocates a new surface with the specified pixel format, width and height. The surface must be freed via surface_free when it is not needed anymore.
A surface allocated via surface_alloc can be used as a RDP frame buffer (passed to rdpq_attach) because it is guaranteed to have the required alignment of 64 bytes, provided it is using one of the formats supported by RDP as a framebuffer target (FMT_RGBA32
, FMT_RGBA16
or FMT_I8
).
[in] | format | Pixel format of the surface |
[in] | width | Width in pixels |
[in] | height | Height in pixels |
surface_t surface_make_sub | ( | surface_t * | parent, |
uint16_t | x0, | ||
uint16_t | y0, | ||
uint16_t | width, | ||
uint16_t | height | ||
) |
Initialize a surface_t structure, pointing to a rectangular portion of another surface.
The surface returned by this function will point to a portion of the buffer of the parent surface, and will have of course the same pixel format.
[in] | parent | Parent surface that will be pointed to |
[in] | x0 | X coordinate of the top-left corner within the parent surface |
[in] | y0 | Y coordinate of the top-left corner within the parent surface |
[in] | width | Width of the surface that will be returned |
[in] | height | Height of the surface that will be returned |
void surface_free | ( | surface_t * | surface | ) |
Free the buffer allocated in a surface.
This function should be called after a surface allocated via surface_alloc is not needed anymore.
Calling this function on surfaces allocated via surface_make or surface_make_sub (that is, surfaces initialized with an existing buffer pointer) has no effect but clearing the contents of the surface structure.
[in] | surface | The surface to free |
|
inline |
Returns the pixel format of a surface.
[in] | surface | Surface |
|
inline |
Checks whether this surface owns the buffer that it contains.
[in] | surface | Surface |
|
inline |
Create a placeholder surface, that can be used during rdpq block recording.
When recording a rspq block (via rspq_block_begin / rspq_block_end) it might be useful sometimes to issue draw commands that refer to a surface, but allowing the actual surface to change later at any time.
See rdpq_set_lookup_address for more information.
index | Index that will be used to lookup the surface at playback time |
format | Pixel format |
width | Width of the surface in pixels |
height | Height of the surface in pixels |
stride | Stride of the surface in bytes |
|
inline |
Create a linear placeholder surface, that can be used during rdpq block recording.
This function is similar to surface_make_placeholder, but it creates a surface that is linearly mapped with no per-line padding or extraneous data. (so the stride is automatically deduced from the width).
index | Index that will be used to lookup the surface at playback time |
format | Pixel format |
width | Width of the surface in pixels |
height | Height of the surface in pixels |
|
inline |
Returns the lookup index of a placeholder surface.
If the surface is a placeholder, this function returns the associated lookup index that will be used to retrieve the actual surface at playback time. Otherwise, if it is a normal surface, this function will return 0.
surface | Placeholder surface |