dlist: prelock ctx->Shared->DisplayList before execute_list
authorPierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Mon, 14 Jun 2021 19:18:50 +0000 (21:18 +0200)
committerMarge Bot <eric+marge@anholt.net>
Fri, 9 Jul 2021 10:05:46 +0000 (10:05 +0000)
Together with the glCallList change this transforms this sequence:
  lock - execute - unlock - lock - execute - unlock - ...
In this sequence :
  lock - execute - execute - execute - ... - unlock

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11493>

src/mesa/main/dlist.c
src/mesa/main/dlist.h

index bbb2f36..e8572ec 100644 (file)
@@ -952,7 +952,7 @@ build_bitmap_atlas(struct gl_context *ctx, struct gl_bitmap_atlas *atlas,
     * bitmap in the atlas to determine the texture atlas size.
     */
    for (i = 0; i < atlas->numBitmaps; i++) {
-      const struct gl_display_list *list = _mesa_lookup_list(ctx, listBase + i, false);
+      const struct gl_display_list *list = _mesa_lookup_list(ctx, listBase + i, true);
       const Node *n;
       struct gl_bitmap_glyph *g = &atlas->glyphs[i];
       unsigned bitmap_width, bitmap_height;
@@ -1061,7 +1061,7 @@ build_bitmap_atlas(struct gl_context *ctx, struct gl_bitmap_atlas *atlas,
    memset(map, 0xff, map_stride * atlas->texHeight);
 
    for (i = 0; i < atlas->numBitmaps; i++) {
-      const struct gl_display_list *list = _mesa_lookup_list(ctx, listBase + i, false);
+      const struct gl_display_list *list = _mesa_lookup_list(ctx, listBase + i, true);
       const Node *n = list->Head;
 
       assert(n[0].opcode == OPCODE_BITMAP ||
@@ -1432,8 +1432,10 @@ destroy_list(struct gl_context *ctx, GLuint list)
                      check_atlas_for_deleted_list, &list);
    }
 
+   _mesa_HashLockMutex(ctx->Shared->DisplayList);
    _mesa_delete_list(ctx, dlist);
-   _mesa_HashRemove(ctx->Shared->DisplayList, list);
+   _mesa_HashRemoveLocked(ctx->Shared->DisplayList, list);
+   _mesa_HashUnlockMutex(ctx->Shared->DisplayList);
 }
 
 
@@ -11193,10 +11195,11 @@ _mesa_compile_error(struct gl_context *ctx, GLenum error, const char *s)
  */
 bool
 _mesa_get_list(struct gl_context *ctx, GLuint list,
-               struct gl_display_list **dlist)
+               struct gl_display_list **dlist,
+               bool locked)
 {
    struct gl_display_list * dl =
-      list > 0 ? _mesa_lookup_list(ctx, list, false) : NULL;
+      list > 0 ? _mesa_lookup_list(ctx, list, locked) : NULL;
 
    if (dlist)
       *dlist = dl;
@@ -11215,6 +11218,7 @@ _mesa_get_list(struct gl_context *ctx, GLuint list,
  * Execute a display list.  Note that the ListBase offset must have already
  * been added before calling this function.  I.e. the list argument is
  * the absolute list number, not relative to ListBase.
+ * Must be called with ctx->Shared->DisplayList locked.
  * \param list - display list number
  */
 static void
@@ -11223,7 +11227,7 @@ execute_list(struct gl_context *ctx, GLuint list)
    struct gl_display_list *dlist;
    Node *n;
 
-   if (list == 0 || !_mesa_get_list(ctx, list, &dlist))
+   if (list == 0 || !_mesa_get_list(ctx, list, &dlist, true))
       return;
 
    if (ctx->ListState.CallDepth == MAX_LIST_NESTING) {
@@ -11304,7 +11308,9 @@ execute_list(struct gl_context *ctx, GLuint list)
             break;
          case OPCODE_CALL_LISTS:
             if (ctx->ListState.CallDepth < MAX_LIST_NESTING) {
+               _mesa_HashUnlockMutex(ctx->Shared->DisplayList);
                CALL_CallLists(ctx->Exec, (n[1].i, n[2].e, get_pointer(&n[3])));
+               _mesa_HashLockMutex(ctx->Shared->DisplayList);
             }
             break;
          case OPCODE_CLEAR:
@@ -13453,7 +13459,7 @@ _mesa_IsList(GLuint list)
    GET_CURRENT_CONTEXT(ctx);
    FLUSH_VERTICES(ctx, 0, 0);      /* must be called before assert */
    ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
-   return _mesa_get_list(ctx, list, NULL);
+   return _mesa_get_list(ctx, list, NULL, false);
 }
 
 
@@ -13687,7 +13693,9 @@ _mesa_CallList(GLuint list)
       ctx->CompileFlag = GL_FALSE;
    }
 
+   _mesa_HashLockMutex(ctx->Shared->DisplayList);
    execute_list(ctx, list);
+   _mesa_HashUnlockMutex(ctx->Shared->DisplayList);
    ctx->CompileFlag = save_compile_flag;
 
    /* also restore API function pointers to point to "save" versions */
@@ -13806,6 +13814,8 @@ _mesa_CallLists(GLsizei n, GLenum type, const GLvoid * lists)
 
    GLuint base = ctx->List.ListBase;
 
+   _mesa_HashLockMutex(ctx->Shared->DisplayList);
+
    /* A loop inside a switch is faster than a switch inside a loop. */
    switch (type) {
    case GL_BYTE:
@@ -13872,6 +13882,7 @@ _mesa_CallLists(GLsizei n, GLenum type, const GLvoid * lists)
       break;
    }
 
+   _mesa_HashUnlockMutex(ctx->Shared->DisplayList);
    ctx->CompileFlag = save_compile_flag;
 
    /* also restore API function pointers to point to "save" versions */
@@ -14573,7 +14584,7 @@ print_list(struct gl_context *ctx, GLuint list, const char *fname)
          return;
    }
 
-   if (!_mesa_get_list(ctx, list, &dlist)) {
+   if (!_mesa_get_list(ctx, list, &dlist, true)) {
       fprintf(f, "%u is not a display list ID\n", list);
       fflush(f);
       if (fname)
@@ -14868,7 +14879,7 @@ _mesa_glthread_execute_list(struct gl_context *ctx, GLuint list)
 
    if (list == 0 ||
        ctx->GLThread.ListCallDepth == MAX_LIST_NESTING ||
-       !_mesa_get_list(ctx, list, &dlist))
+       !_mesa_get_list(ctx, list, &dlist, true))
       return;
 
    ctx->GLThread.ListCallDepth++;
index 3d84f17..205e87d 100644 (file)
@@ -129,6 +129,7 @@ _mesa_init_display_list(struct gl_context * ctx);
 
 bool
 _mesa_get_list(struct gl_context *ctx, GLuint list,
-               struct gl_display_list **dlist);
+               struct gl_display_list **dlist,
+               bool locked);
 
 #endif /* DLIST_H */