[Mesa-dev] [PATCH] gallium: Deallocate screens and buffers on exit.
Ricardo Barreira
rsf at google.com
Wed Dec 13 12:18:47 UTC 2017
This allows dclose()'ing this code in dynamically-linked library without
leaking memory.
---
src/gallium/state_trackers/osmesa/osmesa.c | 77 +++++++++++++++++++++---------
1 file changed, 55 insertions(+), 22 deletions(-)
diff --git a/src/gallium/state_trackers/osmesa/osmesa.c b/src/gallium/state_trackers/osmesa/osmesa.c
index 8baec0a0e4..7336dbd0c5 100644
--- a/src/gallium/state_trackers/osmesa/osmesa.c
+++ b/src/gallium/state_trackers/osmesa/osmesa.c
@@ -113,6 +113,11 @@ struct osmesa_context
struct pp_queue_t *pp;
};
+/**
+ * Singleton st_manager object (see get_st_manager / destroy_st_manager
+ * functions).
+ */
+static struct st_manager *stmgr = NULL;
/**
* Linked list of all osmesa_buffers.
@@ -123,7 +128,11 @@ struct osmesa_context
* a frame.
*/
static struct osmesa_buffer *BufferList = NULL;
-
+/*
+ * Indicates whether the cleanup function for BufferList has already been
+ * registered with atexit().
+ */
+static boolean destroy_buffers_registered = FALSE;
/**
* Called from the ST manager.
@@ -149,6 +158,19 @@ get_st_api(void)
return stapi;
}
+/**
+ * Destroy singleton st_manager object.
+ */
+static void
+destroy_st_manager(void)
+{
+ if (stmgr) {
+ if (stmgr->screen) {
+ stmgr->screen->destroy(stmgr->screen);
+ }
+ FREE(stmgr);
+ }
+}
/**
* Create/return a singleton st_manager object.
@@ -156,8 +178,10 @@ get_st_api(void)
static struct st_manager *
get_st_manager(void)
{
- static struct st_manager *stmgr = NULL;
if (!stmgr) {
+ if (atexit(destroy_st_manager) != 0) {
+ return NULL;
+ }
stmgr = CALLOC_STRUCT(st_manager);
if (stmgr) {
stmgr->screen = osmesa_create_screen();
@@ -457,6 +481,24 @@ osmesa_create_st_framebuffer(void)
return stfbi;
}
+static void
+osmesa_destroy_buffer(struct osmesa_buffer *osbuffer)
+{
+ FREE(osbuffer->stfb);
+ FREE(osbuffer);
+}
+
+static void
+destroy_buffers(void)
+{
+ struct osmesa_buffer *buffer;
+ struct osmesa_buffer *next_buffer;
+
+ for (buffer = BufferList; buffer; buffer = next_buffer) {
+ next_buffer = buffer->next;
+ osmesa_destroy_buffer(buffer);
+ }
+}
/**
* Create new buffer and add to linked list.
@@ -466,7 +508,17 @@ osmesa_create_buffer(enum pipe_format color_format,
enum pipe_format ds_format,
enum pipe_format accum_format)
{
- struct osmesa_buffer *osbuffer = CALLOC_STRUCT(osmesa_buffer);
+ struct osmesa_buffer *osbuffer;
+
+ if (!destroy_buffers_registered) {
+ if (atexit(destroy_buffers) != 0) {
+ return NULL;
+ }
+
+ destroy_buffers_registered = TRUE;
+ }
+
+ osbuffer = CALLOC_STRUCT(osmesa_buffer);
if (osbuffer) {
osbuffer->stfb = osmesa_create_st_framebuffer();
@@ -510,22 +562,6 @@ osmesa_find_buffer(enum pipe_format color_format,
}
-static void
-osmesa_destroy_buffer(struct osmesa_buffer *osbuffer)
-{
- struct st_api *stapi = get_st_api();
-
- /*
- * Notify the state manager that the associated framebuffer interface
- * is no longer valid.
- */
- stapi->destroy_drawable(stapi, osbuffer->stfb);
-
- FREE(osbuffer->stfb);
- FREE(osbuffer);
-}
-
-
/**********************************************************************/
/***** Public Functions *****/
@@ -790,9 +826,6 @@ OSMesaMakeCurrent(OSMesaContext osmesa, void *buffer, GLenum type,
osbuffer->height = height;
osbuffer->map = buffer;
- /* XXX unused for now */
- (void) osmesa_destroy_buffer;
-
osmesa->current_buffer = osbuffer;
osmesa->type = type;
--
2.15.1.504.g5279b80103-goog
More information about the mesa-dev
mailing list