From 0193e20df531039e89de089bdb33abd4e2095e19 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 8 Feb 2016 17:50:23 -0700 Subject: [PATCH] mesa: rewrite save_CallLists() code When glCallLists() is compiled into a display list, preserve the call as a single glCallLists rather than 'n' glCallList calls. This will matter for an upcoming display list optimization project. Reviewed-by: Ian Romanick --- src/mesa/main/dlist.c | 61 +++++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 26 deletions(-) diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c index 65f092936b3..fb31d2f2706 100644 --- a/src/mesa/main/dlist.c +++ b/src/mesa/main/dlist.c @@ -194,7 +194,7 @@ typedef enum OPCODE_BLEND_FUNC_SEPARATE_I, OPCODE_CALL_LIST, - OPCODE_CALL_LIST_OFFSET, + OPCODE_CALL_LISTS, OPCODE_CLEAR, OPCODE_CLEAR_ACCUM, OPCODE_CLEAR_COLOR, @@ -706,6 +706,10 @@ _mesa_delete_list(struct gl_context *ctx, struct gl_display_list *dlist) free(get_pointer(&n[10])); n += InstSize[n[0].opcode]; break; + case OPCODE_CALL_LISTS: + free(get_pointer(&n[3])); + n += InstSize[n[0].opcode]; + break; case OPCODE_DRAW_PIXELS: free(get_pointer(&n[5])); n += InstSize[n[0].opcode]; @@ -1569,37 +1573,49 @@ static void GLAPIENTRY save_CallLists(GLsizei num, GLenum type, const GLvoid * lists) { GET_CURRENT_CONTEXT(ctx); - GLint i; - GLboolean typeErrorFlag; + unsigned type_size; + Node *n; + void *lists_copy; SAVE_FLUSH_VERTICES(ctx); switch (type) { case GL_BYTE: case GL_UNSIGNED_BYTE: + type_size = 1; + break; case GL_SHORT: case GL_UNSIGNED_SHORT: + case GL_2_BYTES: + type_size = 2; + break; + case GL_3_BYTES: + type_size = 3; + break; case GL_INT: case GL_UNSIGNED_INT: case GL_FLOAT: - case GL_2_BYTES: - case GL_3_BYTES: case GL_4_BYTES: - typeErrorFlag = GL_FALSE; + type_size = 4; break; default: - typeErrorFlag = GL_TRUE; + type_size = 0; } - for (i = 0; i < num; i++) { - GLint list = translate_id(i, type, lists); - Node *n = alloc_instruction(ctx, OPCODE_CALL_LIST_OFFSET, 2); - if (n) { - n[1].i = list; - n[2].b = typeErrorFlag; - } + if (num > 0 && type_size > 0) { + /* create a copy of the array of list IDs to save in the display list */ + lists_copy = memdup(lists, num * type_size); + } else { + lists_copy = NULL; } + n = alloc_instruction(ctx, OPCODE_CALL_LISTS, 2 + POINTER_DWORDS); + if (n) { + n[1].i = num; + n[2].e = type; + save_pointer(&n[3], lists_copy); + }; + /* After this, we don't know what state we're in. Invalidate all * cached information previously gathered: */ @@ -7772,15 +7788,9 @@ execute_list(struct gl_context *ctx, GLuint list) execute_list(ctx, n[1].ui); } break; - case OPCODE_CALL_LIST_OFFSET: - /* Generated by glCallLists() so we must add ListBase */ - if (n[2].b) { - /* user specified a bad data type at compile time */ - _mesa_error(ctx, GL_INVALID_ENUM, "glCallLists(type)"); - } - else if (ctx->ListState.CallDepth < MAX_LIST_NESTING) { - GLuint list = (GLuint) (ctx->List.ListBase + n[1].i); - execute_list(ctx, list); + case OPCODE_CALL_LISTS: + if (ctx->ListState.CallDepth < MAX_LIST_NESTING) { + CALL_CallLists(ctx->Exec, (n[1].i, n[2].e, get_pointer(&n[3]))); } break; case OPCODE_CLEAR: @@ -9736,9 +9746,8 @@ print_list(struct gl_context *ctx, GLuint list, const char *fname) case OPCODE_CALL_LIST: fprintf(f, "CallList %d\n", (int) n[1].ui); break; - case OPCODE_CALL_LIST_OFFSET: - fprintf(f, "CallList %d + offset %u = %u\n", (int) n[1].ui, - ctx->List.ListBase, ctx->List.ListBase + n[1].ui); + case OPCODE_CALL_LISTS: + fprintf(f, "CallLists %d, %s\n", n[1].i, enum_string(n[1].e)); break; case OPCODE_DISABLE: fprintf(f, "Disable %s\n", enum_string(n[1].e)); -- 2.30.2