From 05579339c0da442669ea75749651e8cf4f9ec39b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Christian=20K=C3=B6nig?= Date: Thu, 1 Mar 2012 23:03:09 +0100 Subject: [PATCH] st/vdpau: make the interface thread save MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- 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 +++++++++++++++---- .../state_trackers/vdpau/presentation.c | 28 ++++++++++--- src/gallium/state_trackers/vdpau/query.c | 30 +++++++++++++- src/gallium/state_trackers/vdpau/surface.c | 25 +++++++++-- .../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 a02bb941ff4..ecc5b158a9b 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 64349a8bbce..56a171fcd87 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 98106a1c702..5af1570d5ae 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 cad577d16b0..e3c9349bfc4 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 15adfadac2e..7e3d74d8011 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 cd00e54a988..d85e656b544 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 c93ae0cac2a..9d4083409a3 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 5ed5c9d88a5..91626022501 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 c12f36f20ce..2898a863243 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; -- 2.30.2