From: Christian König Date: Wed, 16 Dec 2015 19:58:49 +0000 (+0100) Subject: st/va: make the implementation thread safe v2 X-Git-Url: https://git.libre-soc.org/?p=mesa.git;a=commitdiff_plain;h=8479782361ab58eeacee7f81b18d9597553859ce st/va: make the implementation thread safe v2 Otherwise we might crash with MPV. v2: minor cleanups suggested on the list. Signed-off-by: Christian König Reviewed-by: Emil Velikov Reviewed-by: Julien Isorce Tested-by: Julien Isorce --- diff --git a/src/gallium/state_trackers/va/buffer.c b/src/gallium/state_trackers/va/buffer.c index 8de79352b7c..c2c24d693f2 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; - buf = handle_table_get(VL_VA_DRIVER(ctx)->htab, buf_id); - if (!buf) + drv = VL_VA_DRIVER(ctx); + pipe_mutex_lock(drv->mutex); + buf = handle_table_get(drv->htab, buf_id); + 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,11 @@ 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); 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 +285,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,7 +295,9 @@ vlVaAcquireBufferHandle(VADriverContextP ctx, VABufferID buf_id, case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: { struct winsys_handle whandle; + pipe_mutex_lock(drv->mutex); drv->pipe->flush(drv->pipe, NULL, 0); + pipe_mutex_unlock(drv->mutex); memset(&whandle, 0, sizeof(whandle)); whandle.type = DRM_API_HANDLE_TYPE_FD; @@ -299,12 +327,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 192794fefaa..37a011799e2 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 ccc263f77a7..044ce3a1858 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 da9ca5aa6c9..5ae84fc805b 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 && @@ -289,14 +294,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: @@ -322,6 +332,7 @@ vlVaRenderPicture(VADriverContextP ctx, VAContextID context_id, VABufferID *buff break; } } + pipe_mutex_unlock(drv->mutex); return vaStatus; } @@ -339,7 +350,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 f1461894699..f546e566242 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 5ddaf04a8c7..cead10b6bd8 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 bf9d24b2d34..7afd81a196d 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 {