[Mesa-dev] [PATCH 1/9] st/va: make the implementation thread save

Christian König deathsimple at vodafone.de
Wed Dec 16 12:14:33 PST 2015


From: Christian König <christian.koenig at amd.com>

Otherwise we might crash with MPV.

Signed-off-by: Christian König <christian.koenig at amd.com>
---
 src/gallium/state_trackers/va/buffer.c     | 69 +++++++++++++++++++++---------
 src/gallium/state_trackers/va/context.c    |  6 +++
 src/gallium/state_trackers/va/image.c      | 68 +++++++++++++++++++++++------
 src/gallium/state_trackers/va/picture.c    | 19 ++++++--
 src/gallium/state_trackers/va/subpicture.c | 68 ++++++++++++++++++++++-------
 src/gallium/state_trackers/va/surface.c    | 20 +++++++--
 src/gallium/state_trackers/va/va_private.h |  2 +
 7 files changed, 197 insertions(+), 55 deletions(-)

diff --git a/src/gallium/state_trackers/va/buffer.c b/src/gallium/state_trackers/va/buffer.c
index 8de7935..cde1803 100644
--- a/src/gallium/state_trackers/va/buffer.c
+++ b/src/gallium/state_trackers/va/buffer.c
@@ -40,6 +40,7 @@ vlVaCreateBuffer(VADriverContextP ctx, VAContextID context, VABufferType type,
                  unsigned int size, unsigned int num_elements, void *data,
                  VABufferID *buf_id)
 {
+   vlVaDriver *drv;
    vlVaBuffer *buf;
 
    if (!ctx)
@@ -62,7 +63,10 @@ vlVaCreateBuffer(VADriverContextP ctx, VAContextID context, VABufferType type,
    if (data)
       memcpy(buf->data, data, size * num_elements);
 
-   *buf_id = handle_table_add(VL_VA_DRIVER(ctx)->htab, buf);
+   drv = VL_VA_DRIVER(ctx);
+   pipe_mutex_lock(drv->mutex);
+   *buf_id = handle_table_add(drv->htab, buf);
+   pipe_mutex_unlock(drv->mutex);
 
    return VA_STATUS_SUCCESS;
 }
@@ -71,12 +75,16 @@ VAStatus
 vlVaBufferSetNumElements(VADriverContextP ctx, VABufferID buf_id,
                          unsigned int num_elements)
 {
+   vlVaDriver *drv;
    vlVaBuffer *buf;
 
    if (!ctx)
       return VA_STATUS_ERROR_INVALID_CONTEXT;
 
-   buf = handle_table_get(VL_VA_DRIVER(ctx)->htab, buf_id);
+   drv = VL_VA_DRIVER(ctx);
+   pipe_mutex_lock(drv->mutex);
+   buf = handle_table_get(drv->htab, buf_id);
+   pipe_mutex_unlock(drv->mutex);
    if (!buf)
       return VA_STATUS_ERROR_INVALID_BUFFER;
 
@@ -109,22 +117,24 @@ vlVaMapBuffer(VADriverContextP ctx, VABufferID buf_id, void **pbuff)
    if (!pbuff)
       return VA_STATUS_ERROR_INVALID_PARAMETER;
 
+   pipe_mutex_lock(drv->mutex);
    buf = handle_table_get(drv->htab, buf_id);
-   if (!buf)
-      return VA_STATUS_ERROR_INVALID_BUFFER;
-
-   if (buf->export_refcount > 0)
+   if (!buf || buf->export_refcount > 0) {
+      pipe_mutex_unlock(drv->mutex);
       return VA_STATUS_ERROR_INVALID_BUFFER;
+   }
 
    if (buf->derived_surface.resource) {
       *pbuff = pipe_buffer_map(drv->pipe, buf->derived_surface.resource,
                                PIPE_TRANSFER_WRITE,
                                &buf->derived_surface.transfer);
+      pipe_mutex_unlock(drv->mutex);
 
       if (!buf->derived_surface.transfer || !*pbuff)
          return VA_STATUS_ERROR_INVALID_BUFFER;
 
    } else {
+      pipe_mutex_unlock(drv->mutex);
       *pbuff = buf->data;
    }
 
@@ -144,20 +154,23 @@ vlVaUnmapBuffer(VADriverContextP ctx, VABufferID buf_id)
    if (!drv)
       return VA_STATUS_ERROR_INVALID_CONTEXT;
 
+   pipe_mutex_lock(drv->mutex);
    buf = handle_table_get(drv->htab, buf_id);
-   if (!buf)
-      return VA_STATUS_ERROR_INVALID_BUFFER;
-
-   if (buf->export_refcount > 0)
+   if (!buf || buf->export_refcount > 0) {
+      pipe_mutex_unlock(drv->mutex);
       return VA_STATUS_ERROR_INVALID_BUFFER;
+   }
 
    if (buf->derived_surface.resource) {
-      if (!buf->derived_surface.transfer)
+      if (!buf->derived_surface.transfer) {
+         pipe_mutex_unlock(drv->mutex);
          return VA_STATUS_ERROR_INVALID_BUFFER;
+      }
 
       pipe_buffer_unmap(drv->pipe, buf->derived_surface.transfer);
       buf->derived_surface.transfer = NULL;
    }
+   pipe_mutex_unlock(drv->mutex);
 
    return VA_STATUS_SUCCESS;
 }
@@ -165,18 +178,25 @@ vlVaUnmapBuffer(VADriverContextP ctx, VABufferID buf_id)
 VAStatus
 vlVaDestroyBuffer(VADriverContextP ctx, VABufferID buf_id)
 {
+   vlVaDriver *drv;
    vlVaBuffer *buf;
 
    if (!ctx)
       return VA_STATUS_ERROR_INVALID_CONTEXT;
 
+   drv = VL_VA_DRIVER(ctx);
+   pipe_mutex_lock(drv->mutex);
    buf = handle_table_get(VL_VA_DRIVER(ctx)->htab, buf_id);
-   if (!buf)
+   if (!buf) {
+      pipe_mutex_unlock(drv->mutex);
       return VA_STATUS_ERROR_INVALID_BUFFER;
+   }
 
    if (buf->derived_surface.resource) {
-      if (buf->export_refcount > 0)
+      if (buf->export_refcount > 0) {
+         pipe_mutex_unlock(drv->mutex);
          return VA_STATUS_ERROR_INVALID_BUFFER;
+      }
 
       pipe_resource_reference(&buf->derived_surface.resource, NULL);
    }
@@ -184,6 +204,7 @@ vlVaDestroyBuffer(VADriverContextP ctx, VABufferID buf_id)
    FREE(buf->data);
    FREE(buf);
    handle_table_remove(VL_VA_DRIVER(ctx)->htab, buf_id);
+   pipe_mutex_unlock(drv->mutex);
 
    return VA_STATUS_SUCCESS;
 }
@@ -192,12 +213,16 @@ VAStatus
 vlVaBufferInfo(VADriverContextP ctx, VABufferID buf_id, VABufferType *type,
                unsigned int *size, unsigned int *num_elements)
 {
+   vlVaDriver *drv;
    vlVaBuffer *buf;
 
    if (!ctx)
       return VA_STATUS_ERROR_INVALID_CONTEXT;
 
-   buf = handle_table_get(VL_VA_DRIVER(ctx)->htab, buf_id);
+   drv = VL_VA_DRIVER(ctx);
+   pipe_mutex_lock(drv->mutex);
+   buf = handle_table_get(drv->htab, buf_id);
+   pipe_mutex_unlock(drv->mutex);
    if (!buf)
       return VA_STATUS_ERROR_INVALID_BUFFER;
 
@@ -227,7 +252,12 @@ vlVaAcquireBufferHandle(VADriverContextP ctx, VABufferID buf_id,
    if (!ctx)
       return VA_STATUS_ERROR_INVALID_CONTEXT;
 
+   drv = VL_VA_DRIVER(ctx);
+   screen = VL_VA_PSCREEN(ctx);
+   pipe_mutex_lock(drv->mutex);
+   drv->pipe->flush(drv->pipe, NULL, 0);
    buf = handle_table_get(VL_VA_DRIVER(ctx)->htab, buf_id);
+   pipe_mutex_unlock(drv->mutex);
 
    if (!buf)
       return VA_STATUS_ERROR_INVALID_BUFFER;
@@ -256,9 +286,6 @@ vlVaAcquireBufferHandle(VADriverContextP ctx, VABufferID buf_id,
    if (!buf->derived_surface.resource)
       return VA_STATUS_ERROR_INVALID_BUFFER;
 
-   drv = VL_VA_DRIVER(ctx);
-   screen = VL_VA_PSCREEN(ctx);
-
    if (buf->export_refcount > 0) {
       if (buf->export_state.mem_type != mem_type)
          return VA_STATUS_ERROR_INVALID_PARAMETER;
@@ -269,8 +296,6 @@ vlVaAcquireBufferHandle(VADriverContextP ctx, VABufferID buf_id,
       case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: {
          struct winsys_handle whandle;
 
-         drv->pipe->flush(drv->pipe, NULL, 0);
-
          memset(&whandle, 0, sizeof(whandle));
          whandle.type = DRM_API_HANDLE_TYPE_FD;
 
@@ -299,12 +324,16 @@ vlVaAcquireBufferHandle(VADriverContextP ctx, VABufferID buf_id,
 VAStatus
 vlVaReleaseBufferHandle(VADriverContextP ctx, VABufferID buf_id)
 {
+   vlVaDriver *drv;
    vlVaBuffer *buf;
 
    if (!ctx)
       return VA_STATUS_ERROR_INVALID_CONTEXT;
 
-   buf = handle_table_get(VL_VA_DRIVER(ctx)->htab, buf_id);
+   drv = VL_VA_DRIVER(ctx);
+   pipe_mutex_lock(drv->mutex);
+   buf = handle_table_get(drv->htab, buf_id);
+   pipe_mutex_unlock(drv->mutex);
 
    if (!buf)
       return VA_STATUS_ERROR_INVALID_BUFFER;
diff --git a/src/gallium/state_trackers/va/context.c b/src/gallium/state_trackers/va/context.c
index 192794f..37a0117 100644
--- a/src/gallium/state_trackers/va/context.c
+++ b/src/gallium/state_trackers/va/context.c
@@ -155,6 +155,7 @@ VA_DRIVER_INIT_FUNC(VADriverContextP ctx)
 
    vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_BT_601, NULL, true, &drv->csc);
    vl_compositor_set_csc_matrix(&drv->cstate, (const vl_csc_matrix *)&drv->csc);
+   pipe_mutex_init(drv->mutex);
 
    ctx->pDriverData = (void *)drv;
    ctx->version_major = 0;
@@ -262,7 +263,9 @@ vlVaCreateContext(VADriverContextP ctx, VAConfigID config_id, int picture_width,
    }
 
    context->desc.base.profile = config_id;
+   pipe_mutex_lock(drv->mutex);
    *context_id = handle_table_add(drv->htab, context);
+   pipe_mutex_unlock(drv->mutex);
 
    return VA_STATUS_SUCCESS;
 }
@@ -277,6 +280,7 @@ vlVaDestroyContext(VADriverContextP ctx, VAContextID context_id)
       return VA_STATUS_ERROR_INVALID_CONTEXT;
 
    drv = VL_VA_DRIVER(ctx);
+   pipe_mutex_lock(drv->mutex);
    context = handle_table_get(drv->htab, context_id);
 
    if (context->decoder) {
@@ -294,6 +298,7 @@ vlVaDestroyContext(VADriverContextP ctx, VAContextID context_id)
    }
    FREE(context);
    handle_table_remove(drv->htab, context_id);
+   pipe_mutex_unlock(drv->mutex);
 
    return VA_STATUS_SUCCESS;
 }
@@ -312,6 +317,7 @@ vlVaTerminate(VADriverContextP ctx)
    drv->pipe->destroy(drv->pipe);
    drv->vscreen->destroy(drv->vscreen);
    handle_table_destroy(drv->htab);
+   pipe_mutex_destroy(drv->mutex);
    FREE(drv);
 
    return VA_STATUS_SUCCESS;
diff --git a/src/gallium/state_trackers/va/image.c b/src/gallium/state_trackers/va/image.c
index ccc263f..044ce3a 100644
--- a/src/gallium/state_trackers/va/image.c
+++ b/src/gallium/state_trackers/va/image.c
@@ -119,7 +119,9 @@ vlVaCreateImage(VADriverContextP ctx, VAImageFormat *format, int width, int heig
    img = CALLOC(1, sizeof(VAImage));
    if (!img)
       return VA_STATUS_ERROR_ALLOCATION_FAILED;
+   pipe_mutex_lock(drv->mutex);
    img->image_id = handle_table_add(drv->htab, img);
+   pipe_mutex_unlock(drv->mutex);
 
    img->format = *format;
    img->width = width;
@@ -261,6 +263,7 @@ vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image)
       return VA_STATUS_ERROR_ALLOCATION_FAILED;
    }
 
+   pipe_mutex_lock(drv->mutex);
    img->image_id = handle_table_add(drv->htab, img);
 
    img_buf->type = VAImageBufferType;
@@ -270,6 +273,7 @@ vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image)
    pipe_resource_reference(&img_buf->derived_surface.resource, surfaces[0]->texture);
 
    img->buf = handle_table_add(VL_VA_DRIVER(ctx)->htab, img_buf);
+   pipe_mutex_unlock(drv->mutex);
 
    *image = *img;
 
@@ -279,16 +283,22 @@ vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image)
 VAStatus
 vlVaDestroyImage(VADriverContextP ctx, VAImageID image)
 {
+   vlVaDriver *drv;
    VAImage  *vaimage;
 
    if (!ctx)
       return VA_STATUS_ERROR_INVALID_CONTEXT;
 
-   vaimage = handle_table_get(VL_VA_DRIVER(ctx)->htab, image);
-   if (!vaimage)
+   drv = VL_VA_DRIVER(ctx);
+   pipe_mutex_lock(drv->mutex);
+   vaimage = handle_table_get(drv->htab, image);
+   if (!vaimage) {
+      pipe_mutex_unlock(drv->mutex);
       return VA_STATUS_ERROR_INVALID_IMAGE;
+   }
 
    handle_table_remove(VL_VA_DRIVER(ctx)->htab, image);
+   pipe_mutex_unlock(drv->mutex);
    FREE(vaimage);
    return vlVaDestroyBuffer(ctx, vaimage->buf);
 }
@@ -321,21 +331,30 @@ vlVaGetImage(VADriverContextP ctx, VASurfaceID surface, int x, int y,
 
    drv = VL_VA_DRIVER(ctx);
 
+   pipe_mutex_lock(drv->mutex);
    surf = handle_table_get(drv->htab, surface);
-   if (!surf || !surf->buffer)
+   if (!surf || !surf->buffer) {
+      pipe_mutex_unlock(drv->mutex);
       return VA_STATUS_ERROR_INVALID_SURFACE;
+   }
 
    vaimage = handle_table_get(drv->htab, image);
-   if (!vaimage)
+   if (!vaimage) {
+      pipe_mutex_unlock(drv->mutex);
       return VA_STATUS_ERROR_INVALID_IMAGE;
+   }
 
    img_buf = handle_table_get(drv->htab, vaimage->buf);
-   if (!img_buf)
+   if (!img_buf) {
+      pipe_mutex_unlock(drv->mutex);
       return VA_STATUS_ERROR_INVALID_BUFFER;
+   }
 
    format = VaFourccToPipeFormat(vaimage->format.fourcc);
-   if (format == PIPE_FORMAT_NONE)
+   if (format == PIPE_FORMAT_NONE) {
+      pipe_mutex_unlock(drv->mutex);
       return VA_STATUS_ERROR_OPERATION_FAILED;
+   }
 
    if (format != surf->buffer->buffer_format) {
       /* support NV12 to YV12 and IYUV conversion now only */
@@ -344,13 +363,17 @@ vlVaGetImage(VADriverContextP ctx, VASurfaceID surface, int x, int y,
           (format == PIPE_FORMAT_IYUV &&
           surf->buffer->buffer_format == PIPE_FORMAT_NV12))
          convert = true;
-      else
+      else {
+         pipe_mutex_unlock(drv->mutex);
          return VA_STATUS_ERROR_OPERATION_FAILED;
+      }
    }
 
    views = surf->buffer->get_sampler_view_planes(surf->buffer);
-   if (!views)
+   if (!views) {
+      pipe_mutex_unlock(drv->mutex);
       return VA_STATUS_ERROR_OPERATION_FAILED;
+   }
 
    for (i = 0; i < vaimage->num_planes; i++) {
       data[i] = img_buf->data + vaimage->offsets[i];
@@ -377,8 +400,10 @@ vlVaGetImage(VADriverContextP ctx, VASurfaceID surface, int x, int y,
          uint8_t *map;
          map = drv->pipe->transfer_map(drv->pipe, views[i]->texture, 0,
                   PIPE_TRANSFER_READ, &box, &transfer);
-         if (!map)
+         if (!map) {
+            pipe_mutex_unlock(drv->mutex);
             return VA_STATUS_ERROR_OPERATION_FAILED;
+         }
 
          if (i == 1 && convert) {
             u_copy_nv12_to_yv12(data, pitches, i, j,
@@ -393,6 +418,7 @@ vlVaGetImage(VADriverContextP ctx, VASurfaceID surface, int x, int y,
          pipe_transfer_unmap(drv->pipe, transfer);
       }
    }
+   pipe_mutex_unlock(drv->mutex);
 
    return VA_STATUS_SUCCESS;
 }
@@ -415,28 +441,38 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image,
       return VA_STATUS_ERROR_INVALID_CONTEXT;
 
    drv = VL_VA_DRIVER(ctx);
+   pipe_mutex_lock(drv->mutex);
 
    surf = handle_table_get(drv->htab, surface);
-   if (!surf || !surf->buffer)
+   if (!surf || !surf->buffer) {
+      pipe_mutex_unlock(drv->mutex);
       return VA_STATUS_ERROR_INVALID_SURFACE;
+   }
 
    vaimage = handle_table_get(drv->htab, image);
-   if (!vaimage)
+   if (!vaimage) {
+      pipe_mutex_unlock(drv->mutex);
       return VA_STATUS_ERROR_INVALID_IMAGE;
+   }
 
    img_buf = handle_table_get(drv->htab, vaimage->buf);
-   if (!img_buf)
+   if (!img_buf) {
+      pipe_mutex_unlock(drv->mutex);
       return VA_STATUS_ERROR_INVALID_BUFFER;
+   }
 
    if (img_buf->derived_surface.resource) {
       /* Attempting to transfer derived image to surface */
+      pipe_mutex_unlock(drv->mutex);
       return VA_STATUS_ERROR_UNIMPLEMENTED;
    }
 
    format = VaFourccToPipeFormat(vaimage->format.fourcc);
 
-   if (format == PIPE_FORMAT_NONE)
+   if (format == PIPE_FORMAT_NONE) {
+      pipe_mutex_unlock(drv->mutex);
       return VA_STATUS_ERROR_OPERATION_FAILED;
+   }
 
    if (format != surf->buffer->buffer_format) {
       struct pipe_video_buffer *tmp_buf;
@@ -447,6 +483,7 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image,
 
       if (!tmp_buf) {
          surf->templat.buffer_format = old_surf_format;
+         pipe_mutex_unlock(drv->mutex);
          return VA_STATUS_ERROR_ALLOCATION_FAILED;
       }
 
@@ -455,8 +492,10 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image,
    }
 
    views = surf->buffer->get_sampler_view_planes(surf->buffer);
-   if (!views)
+   if (!views) {
+      pipe_mutex_unlock(drv->mutex);
       return VA_STATUS_ERROR_OPERATION_FAILED;
+   }
 
    for (i = 0; i < vaimage->num_planes; i++) {
       data[i] = img_buf->data + vaimage->offsets[i];
@@ -485,6 +524,7 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image,
             pitches[i] * views[i]->texture->array_size, 0);
       }
    }
+   pipe_mutex_unlock(drv->mutex);
 
    return VA_STATUS_SUCCESS;
 }
diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c
index 7b30bf8..3b363fb 100644
--- a/src/gallium/state_trackers/va/picture.c
+++ b/src/gallium/state_trackers/va/picture.c
@@ -50,17 +50,22 @@ vlVaBeginPicture(VADriverContextP ctx, VAContextID context_id, VASurfaceID rende
    if (!drv)
       return VA_STATUS_ERROR_INVALID_CONTEXT;
 
+   pipe_mutex_lock(drv->mutex);
    context = handle_table_get(drv->htab, context_id);
-   if (!context)
+   if (!context) {
+      pipe_mutex_unlock(drv->mutex);
       return VA_STATUS_ERROR_INVALID_CONTEXT;
+   }
 
    surf = handle_table_get(drv->htab, render_target);
+   pipe_mutex_unlock(drv->mutex);
    if (!surf || !surf->buffer)
       return VA_STATUS_ERROR_INVALID_SURFACE;
 
    context->target = surf->buffer;
 
    if (!context->decoder) {
+
       /* VPP */
       if (context->templat.profile == PIPE_VIDEO_PROFILE_UNKNOWN &&
          ((context->target->buffer_format != PIPE_FORMAT_B8G8R8A8_UNORM  &&
@@ -281,14 +286,19 @@ vlVaRenderPicture(VADriverContextP ctx, VAContextID context_id, VABufferID *buff
    if (!drv)
       return VA_STATUS_ERROR_INVALID_CONTEXT;
 
+   pipe_mutex_lock(drv->mutex);
    context = handle_table_get(drv->htab, context_id);
-   if (!context)
+   if (!context) {
+      pipe_mutex_unlock(drv->mutex);
       return VA_STATUS_ERROR_INVALID_CONTEXT;
+   }
 
    for (i = 0; i < num_buffers; ++i) {
       vlVaBuffer *buf = handle_table_get(drv->htab, buffers[i]);
-      if (!buf)
+      if (!buf) {
+         pipe_mutex_unlock(drv->mutex);
          return VA_STATUS_ERROR_INVALID_BUFFER;
+      }
 
       switch (buf->type) {
       case VAPictureParameterBufferType:
@@ -314,6 +324,7 @@ vlVaRenderPicture(VADriverContextP ctx, VAContextID context_id, VABufferID *buff
          break;
       }
    }
+   pipe_mutex_unlock(drv->mutex);
 
    return vaStatus;
 }
@@ -331,7 +342,9 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id)
    if (!drv)
       return VA_STATUS_ERROR_INVALID_CONTEXT;
 
+   pipe_mutex_lock(drv->mutex);
    context = handle_table_get(drv->htab, context_id);
+   pipe_mutex_unlock(drv->mutex);
    if (!context)
       return VA_STATUS_ERROR_INVALID_CONTEXT;
 
diff --git a/src/gallium/state_trackers/va/subpicture.c b/src/gallium/state_trackers/va/subpicture.c
index f146189..f546e56 100644
--- a/src/gallium/state_trackers/va/subpicture.c
+++ b/src/gallium/state_trackers/va/subpicture.c
@@ -65,22 +65,30 @@ VAStatus
 vlVaCreateSubpicture(VADriverContextP ctx, VAImageID image,
                      VASubpictureID *subpicture)
 {
+   vlVaDriver *drv;
    vlVaSubpicture *sub;
    VAImage *img;
 
    if (!ctx)
       return VA_STATUS_ERROR_INVALID_CONTEXT;
 
-   img = handle_table_get(VL_VA_DRIVER(ctx)->htab, image);
-   if (!img)
+   drv = VL_VA_DRIVER(ctx);
+   pipe_mutex_lock(drv->mutex);
+   img = handle_table_get(drv->htab, image);
+   if (!img) {
+      pipe_mutex_unlock(drv->mutex);
       return VA_STATUS_ERROR_INVALID_IMAGE;
+   }
 
    sub = CALLOC(1, sizeof(*sub));
-   if (!sub)
+   if (!sub) {
+      pipe_mutex_unlock(drv->mutex);
       return VA_STATUS_ERROR_ALLOCATION_FAILED;
+   }
 
    sub->image = img;
    *subpicture = handle_table_add(VL_VA_DRIVER(ctx)->htab, sub);
+   pipe_mutex_unlock(drv->mutex);
 
    return VA_STATUS_SUCCESS;
 }
@@ -88,17 +96,24 @@ vlVaCreateSubpicture(VADriverContextP ctx, VAImageID image,
 VAStatus
 vlVaDestroySubpicture(VADriverContextP ctx, VASubpictureID subpicture)
 {
+   vlVaDriver *drv;
    vlVaSubpicture *sub;
 
    if (!ctx)
       return VA_STATUS_ERROR_INVALID_CONTEXT;
 
-   sub = handle_table_get(VL_VA_DRIVER(ctx)->htab, subpicture);
-   if (!sub)
+   drv = VL_VA_DRIVER(ctx);
+   pipe_mutex_lock(drv->mutex);
+
+   sub = handle_table_get(drv->htab, subpicture);
+   if (!sub) {
+      pipe_mutex_unlock(drv->mutex);
       return VA_STATUS_ERROR_INVALID_SUBPICTURE;
+   }
 
    FREE(sub);
-   handle_table_remove(VL_VA_DRIVER(ctx)->htab, subpicture);
+   handle_table_remove(drv->htab, subpicture);
+   pipe_mutex_unlock(drv->mutex);
 
    return VA_STATUS_SUCCESS;
 }
@@ -106,17 +121,24 @@ vlVaDestroySubpicture(VADriverContextP ctx, VASubpictureID subpicture)
 VAStatus
 vlVaSubpictureImage(VADriverContextP ctx, VASubpictureID subpicture, VAImageID image)
 {
+   vlVaDriver *drv;
    vlVaSubpicture *sub;
    VAImage *img;
 
    if (!ctx)
       return VA_STATUS_ERROR_INVALID_CONTEXT;
 
-   img = handle_table_get(VL_VA_DRIVER(ctx)->htab, image);
-   if (!img)
+   drv = VL_VA_DRIVER(ctx);
+   pipe_mutex_lock(drv->mutex);
+
+   img = handle_table_get(drv->htab, image);
+   if (!img) {
+      pipe_mutex_unlock(drv->mutex);
       return VA_STATUS_ERROR_INVALID_IMAGE;
+   }
 
-   sub = handle_table_get(VL_VA_DRIVER(ctx)->htab, subpicture);
+   sub = handle_table_get(drv->htab, subpicture);
+   pipe_mutex_unlock(drv->mutex);
    if (!sub)
       return VA_STATUS_ERROR_INVALID_SUBPICTURE;
 
@@ -164,15 +186,20 @@ vlVaAssociateSubpicture(VADriverContextP ctx, VASubpictureID subpicture,
    if (!ctx)
       return VA_STATUS_ERROR_INVALID_CONTEXT;
    drv = VL_VA_DRIVER(ctx);
+   pipe_mutex_lock(drv->mutex);
 
    sub = handle_table_get(drv->htab, subpicture);
-   if (!sub)
+   if (!sub) {
+      pipe_mutex_unlock(drv->mutex);
       return VA_STATUS_ERROR_INVALID_SUBPICTURE;
+   }
 
    for (i = 0; i < num_surfaces; i++) {
       surf = handle_table_get(drv->htab, target_surfaces[i]);
-      if (!surf)
+      if (!surf) {
+         pipe_mutex_unlock(drv->mutex);
          return VA_STATUS_ERROR_INVALID_SURFACE;
+      }
    }
 
    sub->src_rect = src_rect;
@@ -191,8 +218,10 @@ vlVaAssociateSubpicture(VADriverContextP ctx, VASubpictureID subpicture,
    tex_temp.flags = 0;
    if (!drv->pipe->screen->is_format_supported(
           drv->pipe->screen, tex_temp.format, tex_temp.target,
-          tex_temp.nr_samples, tex_temp.bind))
+          tex_temp.nr_samples, tex_temp.bind)) {
+      pipe_mutex_unlock(drv->mutex);
       return VA_STATUS_ERROR_ALLOCATION_FAILED;
+   }
 
    tex = drv->pipe->screen->resource_create(drv->pipe->screen, &tex_temp);
 
@@ -200,13 +229,16 @@ vlVaAssociateSubpicture(VADriverContextP ctx, VASubpictureID subpicture,
    u_sampler_view_default_template(&sampler_templ, tex, tex->format);
    sub->sampler = drv->pipe->create_sampler_view(drv->pipe, tex, &sampler_templ);
    pipe_resource_reference(&tex, NULL);
-   if (!sub->sampler)
+   if (!sub->sampler) {
+      pipe_mutex_unlock(drv->mutex);
       return VA_STATUS_ERROR_ALLOCATION_FAILED;
+   }
 
    for (i = 0; i < num_surfaces; i++) {
       surf = handle_table_get(drv->htab, target_surfaces[i]);
       util_dynarray_append(&surf->subpics, vlVaSubpicture *, sub);
    }
+   pipe_mutex_unlock(drv->mutex);
 
    return VA_STATUS_SUCCESS;
 }
@@ -224,15 +256,20 @@ vlVaDeassociateSubpicture(VADriverContextP ctx, VASubpictureID subpicture,
    if (!ctx)
       return VA_STATUS_ERROR_INVALID_CONTEXT;
    drv = VL_VA_DRIVER(ctx);
+   pipe_mutex_lock(drv->mutex);
 
    sub = handle_table_get(drv->htab, subpicture);
-   if (!sub)
+   if (!sub) {
+      pipe_mutex_unlock(drv->mutex);
       return VA_STATUS_ERROR_INVALID_SUBPICTURE;
+   }
 
    for (i = 0; i < num_surfaces; i++) {
       surf = handle_table_get(drv->htab, target_surfaces[i]);
-      if (!surf)
+      if (!surf) {
+         pipe_mutex_unlock(drv->mutex);
          return VA_STATUS_ERROR_INVALID_SURFACE;
+      }
 
       array = surf->subpics.data;
       if (!array)
@@ -246,6 +283,7 @@ vlVaDeassociateSubpicture(VADriverContextP ctx, VASubpictureID subpicture,
       while (surf->subpics.size && util_dynarray_top(&surf->subpics, vlVaSubpicture *) == NULL)
          (void)util_dynarray_pop(&surf->subpics, vlVaSubpicture *);
    }
+   pipe_mutex_unlock(drv->mutex);
 
    return VA_STATUS_SUCCESS;
 }
diff --git a/src/gallium/state_trackers/va/surface.c b/src/gallium/state_trackers/va/surface.c
index 5ddaf04..cead10b 100644
--- a/src/gallium/state_trackers/va/surface.c
+++ b/src/gallium/state_trackers/va/surface.c
@@ -68,6 +68,7 @@ vlVaDestroySurfaces(VADriverContextP ctx, VASurfaceID *surface_list, int num_sur
       return VA_STATUS_ERROR_INVALID_CONTEXT;
 
    drv = VL_VA_DRIVER(ctx);
+   pipe_mutex_lock(drv->mutex);
    for (i = 0; i < num_surfaces; ++i) {
       vlVaSurface *surf = handle_table_get(drv->htab, surface_list[i]);
       if (surf->buffer)
@@ -76,6 +77,7 @@ vlVaDestroySurfaces(VADriverContextP ctx, VASurfaceID *surface_list, int num_sur
       FREE(surf);
       handle_table_remove(drv->htab, surface_list[i]);
    }
+   pipe_mutex_unlock(drv->mutex);
 
    return VA_STATUS_SUCCESS;
 }
@@ -236,16 +238,21 @@ vlVaPutSurface(VADriverContextP ctx, VASurfaceID surface_id, void* draw, short s
       return VA_STATUS_ERROR_INVALID_CONTEXT;
 
    drv = VL_VA_DRIVER(ctx);
+   pipe_mutex_lock(drv->mutex);
    surf = handle_table_get(drv->htab, surface_id);
-   if (!surf)
+   if (!surf) {
+      pipe_mutex_unlock(drv->mutex);
       return VA_STATUS_ERROR_INVALID_SURFACE;
+   }
 
    screen = drv->pipe->screen;
    vscreen = drv->vscreen;
 
    tex = vscreen->texture_from_drawable(vscreen, draw);
-   if (!tex)
+   if (!tex) {
+      pipe_mutex_unlock(drv->mutex);
       return VA_STATUS_ERROR_INVALID_DISPLAY;
+   }
 
    dirty_area = vscreen->get_dirty_area(vscreen);
 
@@ -254,6 +261,7 @@ vlVaPutSurface(VADriverContextP ctx, VASurfaceID surface_id, void* draw, short s
    surf_draw = drv->pipe->create_surface(drv->pipe, tex, &surf_templ);
    if (!surf_draw) {
       pipe_resource_reference(&tex, NULL);
+      pipe_mutex_unlock(drv->mutex);
       return VA_STATUS_ERROR_INVALID_DISPLAY;
    }
 
@@ -268,8 +276,10 @@ vlVaPutSurface(VADriverContextP ctx, VASurfaceID surface_id, void* draw, short s
    vl_compositor_render(&drv->cstate, &drv->compositor, surf_draw, dirty_area, true);
 
    status = vlVaPutSubpictures(surf, drv, surf_draw, dirty_area, &src_rect, &dst_rect);
-   if (status)
+   if (status) {
+      pipe_mutex_unlock(drv->mutex);
       return status;
+   }
 
    screen->flush_frontbuffer(screen, tex, 0, 0,
                              vscreen->get_private(vscreen), NULL);
@@ -278,6 +288,7 @@ vlVaPutSurface(VADriverContextP ctx, VASurfaceID surface_id, void* draw, short s
 
    pipe_resource_reference(&tex, NULL);
    pipe_surface_reference(&surf_draw, NULL);
+   pipe_mutex_unlock(drv->mutex);
 
    return VA_STATUS_SUCCESS;
 }
@@ -599,6 +610,7 @@ vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int format,
 
    memset(surfaces, VA_INVALID_ID, num_surfaces * sizeof(VASurfaceID));
 
+   pipe_mutex_lock(drv->mutex);
    for (i = 0; i < num_surfaces; i++) {
       vlVaSurface *surf = CALLOC(1, sizeof(vlVaSurface));
       if (!surf)
@@ -627,10 +639,12 @@ vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int format,
          assert(0);
       }
    }
+   pipe_mutex_unlock(drv->mutex);
 
    return VA_STATUS_SUCCESS;
 
 no_res:
+   pipe_mutex_unlock(drv->mutex);
    if (i)
       vlVaDestroySurfaces(ctx, surfaces, i);
 
diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h
index fa6e0fb..204db16 100644
--- a/src/gallium/state_trackers/va/va_private.h
+++ b/src/gallium/state_trackers/va/va_private.h
@@ -44,6 +44,7 @@
 #include "vl/vl_csc.h"
 
 #include "util/u_dynarray.h"
+#include "os/os_thread.h"
 
 #define VL_VA_DRIVER(ctx) ((vlVaDriver *)ctx->pDriverData)
 #define VL_VA_PSCREEN(ctx) (VL_VA_DRIVER(ctx)->vscreen->pscreen)
@@ -203,6 +204,7 @@ typedef struct {
    struct vl_compositor compositor;
    struct vl_compositor_state cstate;
    vl_csc_matrix csc;
+   pipe_mutex mutex;
 } vlVaDriver;
 
 typedef struct {
-- 
2.5.0



More information about the mesa-dev mailing list