diff options
author | Brian Paul <[email protected]> | 2013-11-24 07:04:33 -0700 |
---|---|---|
committer | Brian Paul <[email protected]> | 2013-12-04 15:40:32 -0700 |
commit | 50205e11c60ec2ef64a6408c7a95155afcf8802e (patch) | |
tree | 0587b8819fe69e2d1f0cd28a59e784a63146bd7f /src/mesa/main | |
parent | 314ccf69016d0025ce251155553cc448159a3b10 (diff) |
mesa: reduce memory used for short display lists
Display lists allocate memory in chunks of 256 tokens (1KB) at a time.
If an app creates many short display lists or uses glXUseXFont() this
can waste quite a bit of memory.
This patch uses realloc() to trim short lists and reduce the memory
used.
Also, null/zero-out some list construction fields in _mesa_EndList().
Reviewed-by: Ian Romanick <[email protected]>
Diffstat (limited to 'src/mesa/main')
-rw-r--r-- | src/mesa/main/dlist.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c index d1e203589f7..cb40ff4db88 100644 --- a/src/mesa/main/dlist.c +++ b/src/mesa/main/dlist.c @@ -1067,6 +1067,37 @@ alloc_instruction(struct gl_context *ctx, OpCode opcode, GLuint nparams) } +/** + * Called by EndList to try to reduce memory used for the list. + */ +static void +trim_list(struct gl_context *ctx) +{ + /* If the list we're ending only has one allocated block of nodes/tokens + * and its size isn't a full block size, realloc the block to use less + * memory. This is important for apps that create many small display + * lists and apps that use glXUseXFont (many lists each containing one + * glBitmap call). + * Note: we currently only trim display lists that allocated one block + * of tokens. That hits the short list case which is what we're mainly + * concerned with. Trimming longer lists would involve traversing the + * linked list of blocks. + */ + struct gl_dlist_state *list = &ctx->ListState; + + if ((list->CurrentList->Head == list->CurrentBlock) && + (list->CurrentPos < BLOCK_SIZE)) { + /* There's only one block and it's not full, so realloc */ + GLuint newSize = list->CurrentPos * sizeof(Node); + list->CurrentList->Head = + list->CurrentBlock = realloc(list->CurrentBlock, newSize); + if (!list->CurrentBlock) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glEndList"); + } + } +} + + /* * Display List compilation functions @@ -8242,6 +8273,8 @@ _mesa_EndList(void) (void) alloc_instruction(ctx, OPCODE_END_OF_LIST, 0); + trim_list(ctx); + /* Destroy old list, if any */ destroy_list(ctx, ctx->ListState.CurrentList->Name); @@ -8255,6 +8288,8 @@ _mesa_EndList(void) mesa_print_display_list(ctx->ListState.CurrentList->Name); ctx->ListState.CurrentList = NULL; + ctx->ListState.CurrentBlock = NULL; + ctx->ListState.CurrentPos = 0; ctx->ExecuteFlag = GL_TRUE; ctx->CompileFlag = GL_FALSE; |