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 <ian.d.romanick@intel.com>
This commit is contained in:
Brian Paul 2016-02-08 17:50:23 -07:00
parent 711d5347cf
commit 0193e20df5

View file

@ -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));