[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