[Mesa-dev] [PATCH 3/9] st/vdpau: make the interface thread save

Christian König deathsimple at vodafone.de
Sun Mar 4 03:52:38 PST 2012


Signed-off-by: Christian König <deathsimple at vodafone.de>
---
 src/gallium/state_trackers/vdpau/bitmap.c        |   21 +++++++----
 src/gallium/state_trackers/vdpau/decode.c        |   28 ++++++++++++---
 src/gallium/state_trackers/vdpau/device.c        |    4 ++-
 src/gallium/state_trackers/vdpau/mixer.c         |   31 ++++++++++++++--
 src/gallium/state_trackers/vdpau/output.c        |   41 ++++++++++++++++++----
 src/gallium/state_trackers/vdpau/presentation.c  |   28 ++++++++++++---
 src/gallium/state_trackers/vdpau/query.c         |   30 +++++++++++++++-
 src/gallium/state_trackers/vdpau/surface.c       |   25 +++++++++++--
 src/gallium/state_trackers/vdpau/vdpau_private.h |    2 +
 9 files changed, 175 insertions(+), 35 deletions(-)

diff --git a/src/gallium/state_trackers/vdpau/bitmap.c b/src/gallium/state_trackers/vdpau/bitmap.c
index a02bb94..ecc5b15 100644
--- a/src/gallium/state_trackers/vdpau/bitmap.c
+++ b/src/gallium/state_trackers/vdpau/bitmap.c
@@ -69,7 +69,6 @@ vlVdpBitmapSurfaceCreate(VdpDevice device,
    vlsurface->device = dev;
 
    memset(&res_tmpl, 0, sizeof(res_tmpl));
-
    res_tmpl.target = PIPE_TEXTURE_2D;
    res_tmpl.format = FormatRGBAToPipe(rgba_format);
    res_tmpl.width0 = width;
@@ -78,29 +77,32 @@ vlVdpBitmapSurfaceCreate(VdpDevice device,
    res_tmpl.array_size = 1;
    res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
    res_tmpl.usage = frequently_accessed ? PIPE_USAGE_DYNAMIC : PIPE_USAGE_STATIC;
+
+   pipe_mutex_lock(dev->mutex);
    res = pipe->screen->resource_create(pipe->screen, &res_tmpl);
    if (!res) {
+      pipe_mutex_unlock(dev->mutex);
       FREE(dev);
       return VDP_STATUS_RESOURCES;
    }
 
    vlVdpDefaultSamplerViewTemplate(&sv_templ, res);
    vlsurface->sampler_view = pipe->create_sampler_view(pipe, res, &sv_templ);
+
+   pipe_resource_reference(&res, NULL);
+   pipe_mutex_unlock(dev->mutex);
+
    if (!vlsurface->sampler_view) {
-      pipe_resource_reference(&res, NULL);
       FREE(dev);
       return VDP_STATUS_RESOURCES;
    }
 
    *surface = vlAddDataHTAB(vlsurface);
    if (*surface == 0) {
-      pipe_resource_reference(&res, NULL);
       FREE(dev);
       return VDP_STATUS_ERROR;
    }
 
-   pipe_resource_reference(&res, NULL);
-
    return VDP_STATUS_OK;
 }
 
@@ -116,9 +118,9 @@ vlVdpBitmapSurfaceDestroy(VdpBitmapSurface surface)
    if (!vlsurface)
       return VDP_STATUS_INVALID_HANDLE;
 
-   vlVdpResolveDelayedRendering(vlsurface->device, NULL, NULL);
-
+   pipe_mutex_lock(vlsurface->device->mutex);
    pipe_sampler_view_reference(&vlsurface->sampler_view, NULL);
+   pipe_mutex_unlock(vlsurface->device->mutex);
 
    vlRemoveDataHTAB(surface);
    FREE(vlsurface);
@@ -177,11 +179,16 @@ vlVdpBitmapSurfacePutBitsNative(VdpBitmapSurface surface,
 
    pipe = vlsurface->device->context;
 
+   pipe_mutex_lock(vlsurface->device->mutex);
+
    vlVdpResolveDelayedRendering(vlsurface->device, NULL, NULL);
 
    dst_box = RectToPipeBox(destination_rect, vlsurface->sampler_view->texture);
    pipe->transfer_inline_write(pipe, vlsurface->sampler_view->texture, 0,
                                PIPE_TRANSFER_WRITE, &dst_box, *source_data,
                                *source_pitches, 0);
+
+   pipe_mutex_unlock(vlsurface->device->mutex);
+
    return VDP_STATUS_OK;
 }
diff --git a/src/gallium/state_trackers/vdpau/decode.c b/src/gallium/state_trackers/vdpau/decode.c
index 64349a8..56a171f 100644
--- a/src/gallium/state_trackers/vdpau/decode.c
+++ b/src/gallium/state_trackers/vdpau/decode.c
@@ -67,18 +67,25 @@ vlVdpDecoderCreate(VdpDevice device,
 
    pipe = dev->context;
    screen = dev->vscreen->pscreen;
+
+   pipe_mutex_lock(dev->mutex);
+
    supported = screen->get_video_param
    (
       screen,
       p_profile,
       PIPE_VIDEO_CAP_SUPPORTED
    );
-   if (!supported)
+   if (!supported) {
+      pipe_mutex_unlock(dev->mutex);
       return VDP_STATUS_INVALID_DECODER_PROFILE;
+   }
 
    vldecoder = CALLOC(1,sizeof(vlVdpDecoder));
-   if (!vldecoder)
+   if (!vldecoder) {
+      pipe_mutex_unlock(dev->mutex);
       return VDP_STATUS_RESOURCES;
+   }
 
    vldecoder->device = dev;
 
@@ -101,14 +108,15 @@ vlVdpDecoderCreate(VdpDevice device,
       ret = VDP_STATUS_ERROR;
       goto error_handle;
    }
+   pipe_mutex_unlock(dev->mutex);
 
    return VDP_STATUS_OK;
 
 error_handle:
-
    vldecoder->decoder->destroy(vldecoder->decoder);
 
 error_decoder:
+   pipe_mutex_unlock(dev->mutex);
    FREE(vldecoder);
    return ret;
 }
@@ -125,7 +133,9 @@ vlVdpDecoderDestroy(VdpDecoder decoder)
    if (!vldecoder)
       return VDP_STATUS_INVALID_HANDLE;
 
+   pipe_mutex_lock(vldecoder->device->mutex);
    vldecoder->decoder->destroy(vldecoder->decoder);
+   pipe_mutex_unlock(vldecoder->device->mutex);
 
    FREE(vldecoder);
 
@@ -415,6 +425,8 @@ vlVdpDecoderRender(VdpDecoder decoder,
       // TODO: Recreate decoder with correct chroma
       return VDP_STATUS_INVALID_CHROMA_TYPE;
 
+   pipe_mutex_lock(vlsurf->device->mutex);
+
    buffer_support[0] = screen->get_video_param(screen, dec->profile, PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE);
    buffer_support[1] = screen->get_video_param(screen, dec->profile, PIPE_VIDEO_CAP_SUPPORTS_INTERLACED);
 
@@ -436,8 +448,10 @@ vlVdpDecoderRender(VdpDecoder decoder,
       vlsurf->video_buffer = dec->context->create_video_buffer(dec->context, &vlsurf->templat);
 
       /* still no luck? get me out of here... */
-      if (!vlsurf->video_buffer)
+      if (!vlsurf->video_buffer) {
+         pipe_mutex_unlock(vlsurf->device->mutex);
          return VDP_STATUS_NO_IMPLEMENTATION;
+      }
    }
 
    memset(&desc, 0, sizeof(desc));
@@ -456,10 +470,13 @@ vlVdpDecoderRender(VdpDecoder decoder,
       ret = vlVdpDecoderRenderH264(&desc.h264, (VdpPictureInfoH264 *)picture_info);
       break;
    default:
+      pipe_mutex_unlock(vlsurf->device->mutex);
       return VDP_STATUS_INVALID_DECODER_PROFILE;
    }
-   if (ret != VDP_STATUS_OK)
+   if (ret != VDP_STATUS_OK) {
+      pipe_mutex_unlock(vlsurf->device->mutex);
       return ret;
+   }
 
    for (i = 0; i < bitstream_buffer_count; ++i) {
       buffers[i] = bitstream_buffers[i].bitstream;
@@ -469,5 +486,6 @@ vlVdpDecoderRender(VdpDecoder decoder,
    dec->begin_frame(dec, vlsurf->video_buffer, &desc.base);
    dec->decode_bitstream(dec, vlsurf->video_buffer, &desc.base, bitstream_buffer_count, buffers, sizes);
    dec->end_frame(dec, vlsurf->video_buffer, &desc.base);
+   pipe_mutex_unlock(vlsurf->device->mutex);
    return ret;
 }
diff --git a/src/gallium/state_trackers/vdpau/device.c b/src/gallium/state_trackers/vdpau/device.c
index 98106a1..5af1570 100644
--- a/src/gallium/state_trackers/vdpau/device.c
+++ b/src/gallium/state_trackers/vdpau/device.c
@@ -80,6 +80,7 @@ vdp_imp_device_create_x11(Display *display, int screen, VdpDevice *device,
    }
 
    vl_compositor_init(&dev->compositor, dev->context);
+   pipe_mutex_init(dev->mutex);
 
    *get_proc_address = &vlVdpGetProcAddress;
 
@@ -161,7 +162,8 @@ vlVdpDeviceDestroy(VdpDevice device)
    vlVdpDevice *dev = vlGetDataHTAB(device);
    if (!dev)
       return VDP_STATUS_INVALID_HANDLE;
-      
+
+   pipe_mutex_destroy(dev->mutex);
    vl_compositor_cleanup(&dev->compositor);
    dev->context->destroy(dev->context);
    vl_screen_destroy(dev->vscreen);
diff --git a/src/gallium/state_trackers/vdpau/mixer.c b/src/gallium/state_trackers/vdpau/mixer.c
index cad577d..e3c9349 100644
--- a/src/gallium/state_trackers/vdpau/mixer.c
+++ b/src/gallium/state_trackers/vdpau/mixer.c
@@ -62,6 +62,9 @@ vlVdpVideoMixerCreate(VdpDevice device,
       return VDP_STATUS_RESOURCES;
 
    vmixer->device = dev;
+
+   pipe_mutex_lock(dev->mutex);
+
    vl_compositor_init_state(&vmixer->cstate, dev->context);
 
    vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_BT_601, NULL, true, &vmixer->csc);
@@ -143,6 +146,7 @@ vlVdpVideoMixerCreate(VdpDevice device,
    }
    vmixer->luma_key_min = 0.f;
    vmixer->luma_key_max = 1.f;
+   pipe_mutex_unlock(dev->mutex);
 
    return VDP_STATUS_OK;
 
@@ -151,6 +155,7 @@ no_params:
 
 no_handle:
    vl_compositor_cleanup_state(&vmixer->cstate);
+   pipe_mutex_unlock(dev->mutex);
    FREE(vmixer);
    return ret;
 }
@@ -167,6 +172,8 @@ vlVdpVideoMixerDestroy(VdpVideoMixer mixer)
    if (!vmixer)
       return VDP_STATUS_INVALID_HANDLE;
 
+   pipe_mutex_lock(vmixer->device->mutex);
+
    vlVdpResolveDelayedRendering(vmixer->device, NULL, NULL);
 
    vlRemoveDataHTAB(mixer);
@@ -182,6 +189,7 @@ vlVdpVideoMixerDestroy(VdpVideoMixer mixer)
       vl_matrix_filter_cleanup(vmixer->sharpness.filter);
       FREE(vmixer->sharpness.filter);
    }
+   pipe_mutex_unlock(vmixer->device->mutex);
 
    FREE(vmixer);
 
@@ -221,8 +229,6 @@ VdpStatus vlVdpVideoMixerRender(VdpVideoMixer mixer,
    if (!vmixer)
       return VDP_STATUS_INVALID_HANDLE;
 
-   vlVdpResolveDelayedRendering(vmixer->device, NULL, NULL);
-
    compositor = &vmixer->device->compositor;
 
    surf = vlGetDataHTAB(video_surface_current);
@@ -244,10 +250,14 @@ VdpStatus vlVdpVideoMixerRender(VdpVideoMixer mixer,
    if (!dst)
       return VDP_STATUS_INVALID_HANDLE;
 
+   pipe_mutex_lock(vmixer->device->mutex);
+   vlVdpResolveDelayedRendering(vmixer->device, NULL, NULL);
    if (background_surface != VDP_INVALID_HANDLE) {
       vlVdpOutputSurface *bg = vlGetDataHTAB(background_surface);
-      if (!bg)
+      if (!bg) {
+         pipe_mutex_unlock(vmixer->device->mutex);
          return VDP_STATUS_INVALID_HANDLE;
+      }
       vl_compositor_set_rgba_layer(&vmixer->cstate, compositor, layer++, bg->sampler_view,
                                    RectToPipe(background_source_rect, &rect), NULL, NULL);
    }
@@ -268,6 +278,7 @@ VdpStatus vlVdpVideoMixerRender(VdpVideoMixer mixer,
       break;
 
    default:
+      pipe_mutex_unlock(vmixer->device->mutex);
       return VDP_STATUS_INVALID_VIDEO_MIXER_PICTURE_STRUCTURE;
    };
    vl_compositor_set_buffer_layer(&vmixer->cstate, compositor, layer, surf->video_buffer,
@@ -276,8 +287,10 @@ VdpStatus vlVdpVideoMixerRender(VdpVideoMixer mixer,
 
    for (i = 0; i < layer_count; ++i) {
       vlVdpOutputSurface *src = vlGetDataHTAB(layers->source_surface);
-      if (!src)
+      if (!src) {
+         pipe_mutex_unlock(vmixer->device->mutex);
          return VDP_STATUS_INVALID_HANDLE;
+      }
 
       assert(layers->struct_version == VDP_LAYER_VERSION);
 
@@ -305,6 +318,7 @@ VdpStatus vlVdpVideoMixerRender(VdpVideoMixer mixer,
          vl_matrix_filter_render(vmixer->sharpness.filter,
                                  dst->sampler_view, dst->surface);
    }
+   pipe_mutex_unlock(vmixer->device->mutex);
 
    return VDP_STATUS_OK;
 }
@@ -452,6 +466,7 @@ vlVdpVideoMixerSetFeatureEnables(VdpVideoMixer mixer,
    if (!vmixer)
       return VDP_STATUS_INVALID_HANDLE;
 
+   pipe_mutex_lock(vmixer->device->mutex);
    for (i = 0; i < feature_count; ++i) {
       switch (features[i]) {
       /* they are valid, but we doesn't support them */
@@ -481,9 +496,11 @@ vlVdpVideoMixerSetFeatureEnables(VdpVideoMixer mixer,
          break;
 
       default:
+         pipe_mutex_unlock(vmixer->device->mutex);
          return VDP_STATUS_INVALID_VIDEO_MIXER_FEATURE;
       }
    }
+   pipe_mutex_unlock(vmixer->device->mutex);
 
    return VDP_STATUS_OK;
 }
@@ -563,6 +580,7 @@ vlVdpVideoMixerSetAttributeValues(VdpVideoMixer mixer,
    if (!vmixer)
       return VDP_STATUS_INVALID_HANDLE;
 
+   pipe_mutex_lock(vmixer->device->mutex);
    for (i = 0; i < attribute_count; ++i) {
       switch (attributes[i]) {
       case VDP_VIDEO_MIXER_ATTRIBUTE_BACKGROUND_COLOR:
@@ -623,9 +641,11 @@ vlVdpVideoMixerSetAttributeValues(VdpVideoMixer mixer,
          vmixer->skip_chroma_deint = *(uint8_t*)attribute_values[i];
          break;
       default:
+         pipe_mutex_unlock(vmixer->device->mutex);
          return VDP_STATUS_INVALID_VIDEO_MIXER_ATTRIBUTE;
       }
    }
+   pipe_mutex_unlock(vmixer->device->mutex);
 
    return VDP_STATUS_OK;
 }
@@ -688,6 +708,7 @@ vlVdpVideoMixerGetAttributeValues(VdpVideoMixer mixer,
    if (!vmixer)
       return VDP_STATUS_INVALID_HANDLE;
 
+   pipe_mutex_lock(vmixer->device->mutex);
    for (i = 0; i < attribute_count; ++i) {
       switch (attributes[i]) {
       case VDP_VIDEO_MIXER_ATTRIBUTE_BACKGROUND_COLOR:
@@ -719,9 +740,11 @@ vlVdpVideoMixerGetAttributeValues(VdpVideoMixer mixer,
          *(uint8_t*)attribute_values[i] = vmixer->skip_chroma_deint;
          break;
       default:
+         pipe_mutex_unlock(vmixer->device->mutex);
          return VDP_STATUS_INVALID_VIDEO_MIXER_ATTRIBUTE;
       }
    }
+   pipe_mutex_unlock(vmixer->device->mutex);
    return VDP_STATUS_OK;
 }
 
diff --git a/src/gallium/state_trackers/vdpau/output.c b/src/gallium/state_trackers/vdpau/output.c
index 15adfad..7e3d74d 100644
--- a/src/gallium/state_trackers/vdpau/output.c
+++ b/src/gallium/state_trackers/vdpau/output.c
@@ -81,8 +81,10 @@ vlVdpOutputSurfaceCreate(VdpDevice device,
    res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
    res_tmpl.usage = PIPE_USAGE_STATIC;
 
+   pipe_mutex_lock(dev->mutex);
    res = pipe->screen->resource_create(pipe->screen, &res_tmpl);
    if (!res) {
+      pipe_mutex_unlock(dev->mutex);
       FREE(dev);
       return VDP_STATUS_ERROR;
    }
@@ -91,6 +93,7 @@ vlVdpOutputSurfaceCreate(VdpDevice device,
    vlsurface->sampler_view = pipe->create_sampler_view(pipe, res, &sv_templ);
    if (!vlsurface->sampler_view) {
       pipe_resource_reference(&res, NULL);
+      pipe_mutex_unlock(dev->mutex);
       FREE(dev);
       return VDP_STATUS_ERROR;
    }
@@ -101,6 +104,7 @@ vlVdpOutputSurfaceCreate(VdpDevice device,
    vlsurface->surface = pipe->create_surface(pipe, res, &surf_templ);
    if (!vlsurface->surface) {
       pipe_resource_reference(&res, NULL);
+      pipe_mutex_unlock(dev->mutex);
       FREE(dev);
       return VDP_STATUS_ERROR;
    }
@@ -108,6 +112,7 @@ vlVdpOutputSurfaceCreate(VdpDevice device,
    *surface = vlAddDataHTAB(vlsurface);
    if (*surface == 0) {
       pipe_resource_reference(&res, NULL);
+      pipe_mutex_unlock(dev->mutex);
       FREE(dev);
       return VDP_STATUS_ERROR;
    }
@@ -116,6 +121,7 @@ vlVdpOutputSurfaceCreate(VdpDevice device,
 
    vl_compositor_init_state(&vlsurface->cstate, pipe);
    vl_compositor_reset_dirty_area(&vlsurface->dirty_area);
+   pipe_mutex_unlock(dev->mutex);
 
    return VDP_STATUS_OK;
 }
@@ -132,11 +138,13 @@ vlVdpOutputSurfaceDestroy(VdpOutputSurface surface)
    if (!vlsurface)
       return VDP_STATUS_INVALID_HANDLE;
 
+   pipe_mutex_lock(vlsurface->device->mutex);
    vlVdpResolveDelayedRendering(vlsurface->device, NULL, NULL);
 
    pipe_surface_reference(&vlsurface->surface, NULL);
    pipe_sampler_view_reference(&vlsurface->sampler_view, NULL);
    vl_compositor_cleanup_state(&vlsurface->cstate);
+   pipe_mutex_unlock(vlsurface->device->mutex);
 
    vlRemoveDataHTAB(surface);
    FREE(vlsurface);
@@ -190,17 +198,21 @@ vlVdpOutputSurfaceGetBitsNative(VdpOutputSurface surface,
    if (!pipe)
       return VDP_STATUS_INVALID_HANDLE;
 
+   pipe_mutex_lock(vlsurface->device->mutex);
    vlVdpResolveDelayedRendering(vlsurface->device, NULL, NULL);
 
    res = vlsurface->sampler_view->texture;
    box = RectToPipeBox(source_rect, res);
    transfer = pipe->get_transfer(pipe, res, 0, PIPE_TRANSFER_READ, &box);
-   if (transfer == NULL)
+   if (transfer == NULL) {
+      pipe_mutex_unlock(vlsurface->device->mutex);
       return VDP_STATUS_RESOURCES;
+   }
 
    map = pipe_transfer_map(pipe, transfer);
    if (map == NULL) {
       pipe_transfer_destroy(pipe, transfer);
+      pipe_mutex_unlock(vlsurface->device->mutex);
       return VDP_STATUS_RESOURCES;
    }
 
@@ -209,6 +221,7 @@ vlVdpOutputSurfaceGetBitsNative(VdpOutputSurface surface,
 
    pipe_transfer_unmap(pipe, transfer);
    pipe_transfer_destroy(pipe, transfer);
+   pipe_mutex_unlock(vlsurface->device->mutex);
 
    return VDP_STATUS_OK;
 }
@@ -235,12 +248,14 @@ vlVdpOutputSurfacePutBitsNative(VdpOutputSurface surface,
    if (!pipe)
       return VDP_STATUS_INVALID_HANDLE;
 
+   pipe_mutex_lock(vlsurface->device->mutex);
    vlVdpResolveDelayedRendering(vlsurface->device, NULL, NULL);
 
    dst_box = RectToPipeBox(destination_rect, vlsurface->sampler_view->texture);
    pipe->transfer_inline_write(pipe, vlsurface->sampler_view->texture, 0,
                                PIPE_TRANSFER_WRITE, &dst_box, *source_data,
                                *source_pitches, 0);
+   pipe_mutex_unlock(vlsurface->device->mutex);
 
    return VDP_STATUS_OK;
 }
@@ -277,8 +292,6 @@ vlVdpOutputSurfacePutBitsIndexed(VdpOutputSurface surface,
    if (!vlsurface)
       return VDP_STATUS_INVALID_HANDLE;
 
-   vlVdpResolveDelayedRendering(vlsurface->device, NULL, NULL);
-
    context = vlsurface->device->context;
    compositor = &vlsurface->device->compositor;
    cstate = &vlsurface->cstate;
@@ -313,6 +326,9 @@ vlVdpOutputSurfacePutBitsIndexed(VdpOutputSurface surface,
    res_tmpl.usage = PIPE_USAGE_STAGING;
    res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW;
 
+   pipe_mutex_lock(vlsurface->device->mutex);
+   vlVdpResolveDelayedRendering(vlsurface->device, NULL, NULL);
+
    res = context->screen->resource_create(context->screen, &res_tmpl);
    if (!res)
       goto error_resource;
@@ -374,12 +390,14 @@ vlVdpOutputSurfacePutBitsIndexed(VdpOutputSurface surface,
 
    pipe_sampler_view_reference(&sv_idx, NULL);
    pipe_sampler_view_reference(&sv_tbl, NULL);
+   pipe_mutex_unlock(vlsurface->device->mutex);
 
    return VDP_STATUS_OK;
 
 error_resource:
    pipe_sampler_view_reference(&sv_idx, NULL);
    pipe_sampler_view_reference(&sv_tbl, NULL);
+   pipe_mutex_unlock(vlsurface->device->mutex);
    return VDP_STATUS_RESOURCES;
 }
 
@@ -411,7 +429,6 @@ vlVdpOutputSurfacePutBitsYCbCr(VdpOutputSurface surface,
    if (!vlsurface)
       return VDP_STATUS_INVALID_HANDLE;
 
-   vlVdpResolveDelayedRendering(vlsurface->device, NULL, NULL);
 
    pipe = vlsurface->device->context;
    compositor = &vlsurface->device->compositor;
@@ -424,6 +441,8 @@ vlVdpOutputSurfacePutBitsYCbCr(VdpOutputSurface surface,
    if (!source_data || !source_pitches)
        return VDP_STATUS_INVALID_POINTER;
 
+   pipe_mutex_lock(vlsurface->device->mutex);
+   vlVdpResolveDelayedRendering(vlsurface->device, NULL, NULL);
    memset(&vtmpl, 0, sizeof(vtmpl));
    vtmpl.buffer_format = format;
    vtmpl.chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420;
@@ -437,12 +456,15 @@ vlVdpOutputSurfacePutBitsYCbCr(VdpOutputSurface surface,
    }
 
    vbuffer = pipe->create_video_buffer(pipe, &vtmpl);
-   if (!vbuffer)
+   if (!vbuffer) {
+      pipe_mutex_unlock(vlsurface->device->mutex);
       return VDP_STATUS_RESOURCES;
+   }
 
    sampler_views = vbuffer->get_sampler_view_planes(vbuffer);
    if (!sampler_views) {
       vbuffer->destroy(vbuffer);
+      pipe_mutex_unlock(vlsurface->device->mutex);
       return VDP_STATUS_RESOURCES;
    }
 
@@ -473,6 +495,7 @@ vlVdpOutputSurfacePutBitsYCbCr(VdpOutputSurface surface,
    vl_compositor_render(cstate, compositor, vlsurface->surface, NULL);
 
    vbuffer->destroy(vbuffer);
+   pipe_mutex_unlock(vlsurface->device->mutex);
 
    return VDP_STATUS_OK;
 }
@@ -624,6 +647,7 @@ vlVdpOutputSurfaceRenderOutputSurface(VdpOutputSurface destination_surface,
    if (dst_vlsurface->device != src_vlsurface->device)
       return VDP_STATUS_HANDLE_DEVICE_MISMATCH;
 
+   pipe_mutex_lock(dst_vlsurface->device->mutex);
    vlVdpResolveDelayedRendering(dst_vlsurface->device, NULL, NULL);
 
    context = dst_vlsurface->device->context;
@@ -641,6 +665,7 @@ vlVdpOutputSurfaceRenderOutputSurface(VdpOutputSurface destination_surface,
    vl_compositor_render(cstate, compositor, dst_vlsurface->surface, NULL);
 
    context->delete_blend_state(context, blend);
+   pipe_mutex_unlock(dst_vlsurface->device->mutex);
 
    return VDP_STATUS_OK;
 }
@@ -681,12 +706,13 @@ vlVdpOutputSurfaceRenderBitmapSurface(VdpOutputSurface destination_surface,
    if (dst_vlsurface->device != src_vlsurface->device)
       return VDP_STATUS_HANDLE_DEVICE_MISMATCH;
 
-   vlVdpResolveDelayedRendering(dst_vlsurface->device, NULL, NULL);
-
    context = dst_vlsurface->device->context;
    compositor = &dst_vlsurface->device->compositor;
    cstate = &dst_vlsurface->cstate;
 
+   pipe_mutex_lock(dst_vlsurface->device->mutex);
+   vlVdpResolveDelayedRendering(dst_vlsurface->device, NULL, NULL);
+
    blend = BlenderToPipe(context, blend_state);
 
    vl_compositor_clear_layers(cstate);
@@ -698,6 +724,7 @@ vlVdpOutputSurfaceRenderBitmapSurface(VdpOutputSurface destination_surface,
    vl_compositor_render(cstate, compositor, dst_vlsurface->surface, NULL);
 
    context->delete_blend_state(context, blend);
+   pipe_mutex_unlock(dst_vlsurface->device->mutex);
 
    return VDP_STATUS_OK;
 }
diff --git a/src/gallium/state_trackers/vdpau/presentation.c b/src/gallium/state_trackers/vdpau/presentation.c
index cd00e54..d85e656 100644
--- a/src/gallium/state_trackers/vdpau/presentation.c
+++ b/src/gallium/state_trackers/vdpau/presentation.c
@@ -65,10 +65,13 @@ vlVdpPresentationQueueCreate(VdpDevice device,
    pq->device = dev;
    pq->drawable = pqt->drawable;
 
+   pipe_mutex_lock(dev->mutex);
    if (!vl_compositor_init_state(&pq->cstate, dev->context)) {
+      pipe_mutex_unlock(dev->mutex);
       ret = VDP_STATUS_ERROR;
       goto no_compositor;
    }
+   pipe_mutex_unlock(dev->mutex);
 
    *presentation_queue = vlAddDataHTAB(pq);
    if (*presentation_queue == 0) {
@@ -96,7 +99,9 @@ vlVdpPresentationQueueDestroy(VdpPresentationQueue presentation_queue)
    if (!pq)
       return VDP_STATUS_INVALID_HANDLE;
 
+   pipe_mutex_lock(pq->device->mutex);
    vl_compositor_cleanup_state(&pq->cstate);
+   pipe_mutex_unlock(pq->device->mutex);
 
    vlRemoveDataHTAB(presentation_queue);
    FREE(pq);
@@ -126,7 +131,9 @@ vlVdpPresentationQueueSetBackgroundColor(VdpPresentationQueue presentation_queue
    color.f[2] = background_color->blue;
    color.f[3] = background_color->alpha;
 
+   pipe_mutex_lock(pq->device->mutex);
    vl_compositor_set_clear_color(&pq->cstate, &color);
+   pipe_mutex_unlock(pq->device->mutex);
 
    return VDP_STATUS_OK;
 }
@@ -148,7 +155,9 @@ vlVdpPresentationQueueGetBackgroundColor(VdpPresentationQueue presentation_queue
    if (!pq)
       return VDP_STATUS_INVALID_HANDLE;
 
+   pipe_mutex_lock(pq->device->mutex);
    vl_compositor_get_clear_color(&pq->cstate, &color);
+   pipe_mutex_unlock(pq->device->mutex);
 
    background_color->red = color.f[0];
    background_color->green = color.f[1];
@@ -174,7 +183,9 @@ vlVdpPresentationQueueGetTime(VdpPresentationQueue presentation_queue,
    if (!pq)
       return VDP_STATUS_INVALID_HANDLE;
 
+   pipe_mutex_lock(pq->device->mutex);
    *current_time = vl_screen_get_timestamp(pq->device->vscreen, pq->drawable);
+   pipe_mutex_unlock(pq->device->mutex);
 
    return VDP_STATUS_OK;
 }
@@ -206,14 +217,20 @@ vlVdpPresentationQueueDisplay(VdpPresentationQueue presentation_queue,
    if (!pq)
       return VDP_STATUS_INVALID_HANDLE;
 
+   surf = vlGetDataHTAB(surface);
+   if (!surf)
+      return VDP_STATUS_INVALID_HANDLE;
 
    pipe = pq->device->context;
    compositor = &pq->device->compositor;
    cstate = &pq->cstate;
 
+   pipe_mutex_lock(pq->device->mutex);
    tex = vl_screen_texture_from_drawable(pq->device->vscreen, pq->drawable);
-   if (!tex)
+   if (!tex) {
+      pipe_mutex_unlock(pq->device->mutex);
       return VDP_STATUS_INVALID_HANDLE;
+   }
 
    dirty_area = vl_screen_get_dirty_area(pq->device->vscreen);
 
@@ -222,10 +239,6 @@ vlVdpPresentationQueueDisplay(VdpPresentationQueue presentation_queue,
    surf_templ.usage = PIPE_BIND_RENDER_TARGET;
    surf_draw = pipe->create_surface(pipe, tex, &surf_templ);
 
-   surf = vlGetDataHTAB(surface);
-   if (!surf)
-      return VDP_STATUS_INVALID_HANDLE;
-
    surf->timestamp = (vlVdpTime)earliest_presentation_time;
 
    dst_clip.x0 = 0;
@@ -280,6 +293,7 @@ vlVdpPresentationQueueDisplay(VdpPresentationQueue presentation_queue,
 
    pipe_resource_reference(&tex, NULL);
    pipe_surface_reference(&surf_draw, NULL);
+   pipe_mutex_unlock(pq->device->mutex);
 
    return VDP_STATUS_OK;
 }
@@ -307,10 +321,12 @@ vlVdpPresentationQueueBlockUntilSurfaceIdle(VdpPresentationQueue presentation_qu
    if (!surf)
       return VDP_STATUS_INVALID_HANDLE;
 
+   pipe_mutex_lock(pq->device->mutex);
    if (surf->fence) {
       screen = pq->device->vscreen->pscreen;
       screen->fence_finish(screen, surf->fence, 0);
    }
+   pipe_mutex_unlock(pq->device->mutex);
 
    return vlVdpPresentationQueueGetTime(presentation_queue, first_presentation_time);
 }
@@ -344,6 +360,7 @@ vlVdpPresentationQueueQuerySurfaceStatus(VdpPresentationQueue presentation_queue
    if (!surf->fence) {
       *status = VDP_PRESENTATION_QUEUE_STATUS_IDLE;
    } else {
+      pipe_mutex_lock(pq->device->mutex);
       screen = pq->device->vscreen->pscreen;
       if (screen->fence_signalled(screen, surf->fence)) {
          screen->fence_reference(screen, &surf->fence, NULL);
@@ -355,6 +372,7 @@ vlVdpPresentationQueueQuerySurfaceStatus(VdpPresentationQueue presentation_queue
       } else {
          *status = VDP_PRESENTATION_QUEUE_STATUS_QUEUED;
       }
+      pipe_mutex_unlock(pq->device->mutex);
    }
 
    return VDP_STATUS_OK;
diff --git a/src/gallium/state_trackers/vdpau/query.c b/src/gallium/state_trackers/vdpau/query.c
index c93ae0c..9d40834 100644
--- a/src/gallium/state_trackers/vdpau/query.c
+++ b/src/gallium/state_trackers/vdpau/query.c
@@ -83,12 +83,15 @@ vlVdpVideoSurfaceQueryCapabilities(VdpDevice device, VdpChromaType surface_chrom
    if (!pscreen)
       return VDP_STATUS_RESOURCES;
 
+   pipe_mutex_lock(dev->mutex);
+
    /* XXX: Current limits */
    *is_supported = true;
    if (surface_chroma_type != VDP_CHROMA_TYPE_420)
       *is_supported = false;
 
    max_2d_texture_level = pscreen->get_param(pscreen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
+   pipe_mutex_unlock(dev->mutex);
    if (!max_2d_texture_level)
       return VDP_STATUS_RESOURCES;
 
@@ -120,12 +123,14 @@ vlVdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities(VdpDevice device, VdpChromaTyp
    if (!pscreen)
       return VDP_STATUS_RESOURCES;
 
+   pipe_mutex_lock(dev->mutex);
    *is_supported = pscreen->is_video_format_supported
    (
       pscreen,
       FormatYCBCRToPipe(bits_ycbcr_format),
       PIPE_VIDEO_PROFILE_UNKNOWN
    );
+   pipe_mutex_unlock(dev->mutex);
 
    return VDP_STATUS_OK;
 }
@@ -159,6 +164,7 @@ vlVdpDecoderQueryCapabilities(VdpDevice device, VdpDecoderProfile profile,
       return VDP_STATUS_OK;
    }
    
+   pipe_mutex_lock(dev->mutex);
    *is_supported = pscreen->get_video_param(pscreen, p_profile, PIPE_VIDEO_CAP_SUPPORTED);
    if (*is_supported) {
       *max_width = pscreen->get_video_param(pscreen, p_profile, PIPE_VIDEO_CAP_MAX_WIDTH); 
@@ -171,6 +177,7 @@ vlVdpDecoderQueryCapabilities(VdpDevice device, VdpDecoderProfile profile,
       *max_level = 0;
       *max_macroblocks = 0;
    }
+   pipe_mutex_unlock(dev->mutex);
 
    return VDP_STATUS_OK;
 }
@@ -201,6 +208,7 @@ vlVdpOutputSurfaceQueryCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba
    if (!(is_supported && max_width && max_height))
       return VDP_STATUS_INVALID_POINTER;
 
+   pipe_mutex_lock(dev->mutex);
    *is_supported = pscreen->is_format_supported
    (
       pscreen, format, PIPE_TEXTURE_3D, 1,
@@ -210,14 +218,17 @@ vlVdpOutputSurfaceQueryCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba
       uint32_t max_2d_texture_level = pscreen->get_param(
          pscreen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
 
-      if (!max_2d_texture_level)
+      if (!max_2d_texture_level) {
+         pipe_mutex_unlock(dev->mutex);
          return VDP_STATUS_ERROR;
+      }
 
       *max_width = *max_height = pow(2, max_2d_texture_level - 1);
    } else {
       *max_width = 0;
       *max_height = 0;
    }
+   pipe_mutex_unlock(dev->mutex);
 
    return VDP_STATUS_OK;
 }
@@ -249,11 +260,13 @@ vlVdpOutputSurfaceQueryGetPutBitsNativeCapabilities(VdpDevice device, VdpRGBAFor
    if (!is_supported)
       return VDP_STATUS_INVALID_POINTER;
 
+   pipe_mutex_lock(dev->mutex);
    *is_supported = pscreen->is_format_supported
    (
       pscreen, format, PIPE_TEXTURE_2D, 1,
       PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET
    );
+   pipe_mutex_unlock(dev->mutex);
 
    return VDP_STATUS_OK;
 }
@@ -296,6 +309,7 @@ vlVdpOutputSurfaceQueryPutBitsIndexedCapabilities(VdpDevice device,
    if (!is_supported)
       return VDP_STATUS_INVALID_POINTER;
 
+   pipe_mutex_lock(dev->mutex);
    *is_supported = pscreen->is_format_supported
    (
       pscreen, rgba_format, PIPE_TEXTURE_2D, 1,
@@ -313,6 +327,7 @@ vlVdpOutputSurfaceQueryPutBitsIndexedCapabilities(VdpDevice device,
       pscreen, colortbl_format, PIPE_TEXTURE_1D, 1,
       PIPE_BIND_SAMPLER_VIEW
    );
+   pipe_mutex_unlock(dev->mutex);
 
    return VDP_STATUS_OK;
 }
@@ -349,6 +364,7 @@ vlVdpOutputSurfaceQueryPutBitsYCbCrCapabilities(VdpDevice device, VdpRGBAFormat
    if (!is_supported)
       return VDP_STATUS_INVALID_POINTER;
 
+   pipe_mutex_lock(dev->mutex);
    *is_supported = pscreen->is_format_supported
    (
       pscreen, rgba_format, PIPE_TEXTURE_2D, 1,
@@ -360,6 +376,7 @@ vlVdpOutputSurfaceQueryPutBitsYCbCrCapabilities(VdpDevice device, VdpRGBAFormat
       pscreen, ycbcr_format,
       PIPE_VIDEO_PROFILE_UNKNOWN
    );
+   pipe_mutex_unlock(dev->mutex);
 
    return VDP_STATUS_OK;
 }
@@ -390,6 +407,7 @@ vlVdpBitmapSurfaceQueryCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba
    if (!(is_supported && max_width && max_height))
       return VDP_STATUS_INVALID_POINTER;
 
+   pipe_mutex_lock(dev->mutex);
    *is_supported = pscreen->is_format_supported
    (
       pscreen, format, PIPE_TEXTURE_3D, 1,
@@ -399,14 +417,17 @@ vlVdpBitmapSurfaceQueryCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba
       uint32_t max_2d_texture_level = pscreen->get_param(
          pscreen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
 
-      if (!max_2d_texture_level)
+      if (!max_2d_texture_level) {
+         pipe_mutex_unlock(dev->mutex);
          return VDP_STATUS_ERROR;
+      }
 
       *max_width = *max_height = pow(2, max_2d_texture_level - 1);
    } else {
       *max_width = 0;
       *max_height = 0;
    }
+   pipe_mutex_unlock(dev->mutex);
 
    return VDP_STATUS_OK;
 }
@@ -467,10 +488,13 @@ vlVdpVideoMixerQueryParameterValueRange(VdpDevice device, VdpVideoMixerParameter
    vlVdpDevice *dev = vlGetDataHTAB(device);
    struct pipe_screen *screen;
    enum pipe_video_profile prof = PIPE_VIDEO_PROFILE_UNKNOWN;
+
    if (!dev)
       return VDP_STATUS_INVALID_HANDLE;
    if (!(min_value && max_value))
       return VDP_STATUS_INVALID_POINTER;
+
+   pipe_mutex_lock(dev->mutex);
    screen = dev->vscreen->pscreen;
    switch (parameter) {
    case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH:
@@ -489,8 +513,10 @@ vlVdpVideoMixerQueryParameterValueRange(VdpDevice device, VdpVideoMixerParameter
 
    case VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE:
    default:
+      pipe_mutex_unlock(dev->mutex);
       return VDP_STATUS_INVALID_VIDEO_MIXER_PARAMETER;
    }
+   pipe_mutex_unlock(dev->mutex);
    return VDP_STATUS_OK;
 }
 
diff --git a/src/gallium/state_trackers/vdpau/surface.c b/src/gallium/state_trackers/vdpau/surface.c
index 5ed5c9d..9162602 100644
--- a/src/gallium/state_trackers/vdpau/surface.c
+++ b/src/gallium/state_trackers/vdpau/surface.c
@@ -73,6 +73,7 @@ vlVdpVideoSurfaceCreate(VdpDevice device, VdpChromaType chroma_type,
    p_surf->device = dev;
    pipe = dev->context;
 
+   pipe_mutex_lock(dev->mutex);
    memset(&p_surf->templat, 0, sizeof(p_surf->templat));
    p_surf->templat.buffer_format = pipe->screen->get_video_param
    (
@@ -90,6 +91,7 @@ vlVdpVideoSurfaceCreate(VdpDevice device, VdpChromaType chroma_type,
       PIPE_VIDEO_CAP_PREFERS_INTERLACED
    );
    p_surf->video_buffer = pipe->create_video_buffer(pipe, &p_surf->templat);
+   pipe_mutex_unlock(dev->mutex);
 
    *surface = vlAddDataHTAB(p_surf);
    if (*surface == 0) {
@@ -123,8 +125,10 @@ vlVdpVideoSurfaceDestroy(VdpVideoSurface surface)
    if (!p_surf)
       return VDP_STATUS_INVALID_HANDLE;
 
+   pipe_mutex_lock(p_surf->device->mutex);
    if (p_surf->video_buffer)
       p_surf->video_buffer->destroy(p_surf->video_buffer);
+   pipe_mutex_unlock(p_surf->device->mutex);
 
    FREE(p_surf);
    return VDP_STATUS_OK;
@@ -189,9 +193,12 @@ vlVdpVideoSurfaceGetBitsYCbCr(VdpVideoSurface surface,
    if (vlsurface->video_buffer == NULL || format != vlsurface->video_buffer->buffer_format)
       return VDP_STATUS_NO_IMPLEMENTATION; /* TODO We don't support conversion (yet) */
 
+   pipe_mutex_lock(vlsurface->device->mutex);
    sampler_views = vlsurface->video_buffer->get_sampler_view_planes(vlsurface->video_buffer);
-   if (!sampler_views)
+   if (!sampler_views) {
+      pipe_mutex_unlock(vlsurface->device->mutex);
       return VDP_STATUS_RESOURCES;
+   }
 
    for (i = 0; i < 3; ++i) {
       struct pipe_sampler_view *sv = sampler_views[i];
@@ -206,12 +213,15 @@ vlVdpVideoSurfaceGetBitsYCbCr(VdpVideoSurface surface,
          uint8_t *map;
 
          transfer = pipe->get_transfer(pipe, sv->texture, 0, PIPE_TRANSFER_READ, &box);
-         if (transfer == NULL)
+         if (transfer == NULL) {
+            pipe_mutex_unlock(vlsurface->device->mutex);
             return VDP_STATUS_RESOURCES;
+         }
 
          map = pipe_transfer_map(pipe, transfer);
          if (map == NULL) {
             pipe_transfer_destroy(pipe, transfer);
+            pipe_mutex_unlock(vlsurface->device->mutex);
             return VDP_STATUS_RESOURCES;
          }
 
@@ -223,6 +233,7 @@ vlVdpVideoSurfaceGetBitsYCbCr(VdpVideoSurface surface,
          pipe_transfer_destroy(pipe, transfer);
       }
    }
+   pipe_mutex_unlock(vlsurface->device->mutex);
 
    return VDP_STATUS_OK;
 }
@@ -253,6 +264,7 @@ vlVdpVideoSurfacePutBitsYCbCr(VdpVideoSurface surface,
    if (!pipe)
       return VDP_STATUS_INVALID_HANDLE;
 
+   pipe_mutex_lock(p_surf->device->mutex);
    if (p_surf->video_buffer == NULL || pformat != p_surf->video_buffer->buffer_format) {
 
       /* destroy the old one */
@@ -266,13 +278,17 @@ vlVdpVideoSurfacePutBitsYCbCr(VdpVideoSurface surface,
       p_surf->video_buffer = pipe->create_video_buffer(pipe, &p_surf->templat);
 
       /* stil no luck? ok forget it we don't support it */
-      if (!p_surf->video_buffer)
+      if (!p_surf->video_buffer) {
+         pipe_mutex_unlock(p_surf->device->mutex);
          return VDP_STATUS_NO_IMPLEMENTATION;
+      }
    }
 
    sampler_views = p_surf->video_buffer->get_sampler_view_planes(p_surf->video_buffer);
-   if (!sampler_views)
+   if (!sampler_views) {
+      pipe_mutex_unlock(p_surf->device->mutex);
       return VDP_STATUS_RESOURCES;
+   }
 
    for (i = 0; i < 3; ++i) {
       struct pipe_sampler_view *sv = sampler_views[i];
@@ -291,6 +307,7 @@ vlVdpVideoSurfacePutBitsYCbCr(VdpVideoSurface surface,
                                      0);
       }
    }
+   pipe_mutex_unlock(p_surf->device->mutex);
 
    return VDP_STATUS_OK;
 }
diff --git a/src/gallium/state_trackers/vdpau/vdpau_private.h b/src/gallium/state_trackers/vdpau/vdpau_private.h
index c12f36f..2898a86 100644
--- a/src/gallium/state_trackers/vdpau/vdpau_private.h
+++ b/src/gallium/state_trackers/vdpau/vdpau_private.h
@@ -38,6 +38,7 @@
 
 #include "util/u_debug.h"
 #include "util/u_rect.h"
+#include "os/os_thread.h"
 
 #include "vl/vl_compositor.h"
 #include "vl/vl_csc.h"
@@ -312,6 +313,7 @@ typedef struct
    struct vl_screen *vscreen;
    struct pipe_context *context;
    struct vl_compositor compositor;
+   pipe_mutex mutex;
 
    struct {
       struct vl_compositor_state *cstate;
-- 
1.7.5.4



More information about the mesa-dev mailing list