[Mesa-dev] [PATCH] mesa: rewrite save_CallLists() code

Ian Romanick idr at freedesktop.org
Tue Feb 9 01:25:41 UTC 2016


On 02/08/2016 05:06 PM, Brian Paul wrote:
> 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.

I think this code is generally better than what was here before, but
reading that last sentence made me die inside just a little. :)

Reviewed-by: Ian Romanick <ian.d.romanick at intel.com>

> ---
>  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 65f0929..fb31d2f 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));
> 



More information about the mesa-dev mailing list