Skip to content

Commit

Permalink
Delayed texture deletion (Fixes #28)
Browse files Browse the repository at this point in the history
  • Loading branch information
thp committed Sep 17, 2022
1 parent a8f15ab commit 57da4f5
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 1 deletion.
8 changes: 8 additions & 0 deletions libvita2d/include/vita2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,16 @@ vita2d_texture *vita2d_create_empty_texture(unsigned int w, unsigned int h);
vita2d_texture *vita2d_create_empty_texture_format(unsigned int w, unsigned int h, SceGxmTextureFormat format);
vita2d_texture *vita2d_create_empty_texture_rendertarget(unsigned int w, unsigned int h, SceGxmTextureFormat format);

// Mark texture for deletion; will be deleted at next vita2d_swap_buffers() or
// when vita2d_gc_textures() is called (to avoid GPU crashes when deleting
// textures still required by the GPU to finish rendering the current frame)
void vita2d_free_texture(vita2d_texture *texture);

// This will be called automatically by vita2d_swap_buffers(), but you can call
// it earlier in case you allocate/deallocate many textures in a single frame;
// returns the number of texture objects freed
int vita2d_gc_textures();

unsigned int vita2d_texture_get_width(const vita2d_texture *texture);
unsigned int vita2d_texture_get_height(const vita2d_texture *texture);
unsigned int vita2d_texture_get_stride(const vita2d_texture *texture);
Expand Down
7 changes: 7 additions & 0 deletions libvita2d/source/vita2d.c
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,10 @@ int vita2d_fini()
// wait until rendering is done
sceGxmFinish(_vita2d_context);

// in case vita2d_free_texture() was called after the last vita2d_swap_buffers(),
// we need to GC textures here again, otherwise we would leak texture objects
vita2d_gc_textures();

// clean up allocations
sceGxmShaderPatcherReleaseFragmentProgram(shaderPatcher, clearFragmentProgram);
sceGxmShaderPatcherReleaseVertexProgram(shaderPatcher, clearVertexProgram);
Expand Down Expand Up @@ -844,6 +848,9 @@ void vita2d_swap_buffers()
frontBufferIndex = backBufferIndex;
backBufferIndex = (backBufferIndex + 1) % DISPLAY_BUFFER_COUNT;
}

// free any textures marked for deletion
vita2d_gc_textures();
}

void vita2d_start_drawing()
Expand Down
43 changes: 42 additions & 1 deletion libvita2d/source/vita2d_texture.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ vita2d_texture * vita2d_create_empty_texture_rendertarget(unsigned int w, unsign
return _vita2d_create_empty_texture_format_advanced(w, h, format, 1);
}

void vita2d_free_texture(vita2d_texture *texture)
static void _vita2d_free_texture_internal(vita2d_texture *texture)
{
if (texture) {
if (texture->gxm_rtgt) {
Expand All @@ -214,6 +214,47 @@ void vita2d_free_texture(vita2d_texture *texture)
}
}

typedef struct texture_freelist_entry texture_freelist_entry;

// TODO: If we store the "next" pointer in vita2d_texture, we can
// use it for an intrusive linked list and don't need to malloc
struct texture_freelist_entry {
vita2d_texture *texture;
texture_freelist_entry *next;
};

// Note: Operations on _texture_freelist are not threadsafe at the moment
static texture_freelist_entry *_texture_freelist = NULL;

void vita2d_free_texture(vita2d_texture *texture)
{
texture_freelist_entry *entry = malloc(sizeof(texture_freelist_entry));
entry->texture = texture;
entry->next = _texture_freelist;
_texture_freelist = entry;
}

int vita2d_gc_textures()
{
if (_texture_freelist == NULL) {
// Nothing to do, exit early without waiting
return 0;
}

// Need to free textures, wait for GPU first
vita2d_wait_rendering_done();

int res = 0;
while (_texture_freelist != NULL) {
texture_freelist_entry *entry = _texture_freelist;
_texture_freelist = entry->next;
_vita2d_free_texture_internal(entry->texture);
free(entry);
++res;
}
return res;
}

unsigned int vita2d_texture_get_width(const vita2d_texture *texture)
{
return sceGxmTextureGetWidth(&texture->gxm_tex);
Expand Down

0 comments on commit 57da4f5

Please sign in to comment.