diff options
author | Dmitry Osipenko <digetx@gmail.com> | 2017-12-27 21:00:55 +0300 |
---|---|---|
committer | Dmitry Osipenko <digetx@gmail.com> | 2017-12-28 16:38:27 +0300 |
commit | 3fbb7186859307f8a5508d89a7c16e216b814747 (patch) | |
tree | 59a89a8937cacb367ebdcc05644898ec04931dea | |
parent | b7e346b4465ce70bfd8b53b11d1c2fd8e62614a8 (diff) |
Harden lockings
-rw-r--r-- | src/presentation_queue.c | 2 | ||||
-rw-r--r-- | src/surface.c | 20 | ||||
-rw-r--r-- | src/surface_bitmap.c | 5 | ||||
-rw-r--r-- | src/surface_mixer.c | 27 | ||||
-rw-r--r-- | src/surface_output.c | 10 | ||||
-rw-r--r-- | src/surface_shared.c | 10 | ||||
-rw-r--r-- | src/surface_video.c | 10 | ||||
-rw-r--r-- | src/vdpau_tegra.h | 1 |
8 files changed, 76 insertions, 9 deletions
diff --git a/src/presentation_queue.c b/src/presentation_queue.c index 524d0a3..19fb167 100644 --- a/src/presentation_queue.c +++ b/src/presentation_queue.c @@ -71,7 +71,7 @@ static void pqt_display_surface(tegra_pqt *pqt, tegra_surface *surf) surf->shared->dst_y0, surf->shared->dst_width, surf->shared->dst_height); - } else { + } else if (surf->xv_img) { XvPutImage(dev->display, dev->xv_port, pqt->drawable, pqt->gc, surf->xv_img, diff --git a/src/surface.c b/src/surface.c index 107760e..4a4ae1e 100644 --- a/src/surface.c +++ b/src/surface.c @@ -38,22 +38,29 @@ static uint32_t get_unused_surface_id(void) int dynamic_alloc_surface_data(tegra_surface *surf) { + int ret = 0; + + pthread_mutex_lock(&surf->lock); if (!surf->data_allocated) { - return alloc_surface_data(surf); + ret = alloc_surface_data(surf); } + pthread_mutex_unlock(&surf->lock); - return 0; + return ret; } int dynamic_release_surface_data(tegra_surface *surf) { + int ret = 0; + + pthread_mutex_lock(&surf->lock); if (surf->data_allocated) { - return release_surface_data(surf); + ret = release_surface_data(surf); } - surf->data_dirty = false; + pthread_mutex_unlock(&surf->lock); - return 0; + return ret; } int alloc_surface_data(tegra_surface *surf) @@ -439,12 +446,13 @@ VdpStatus unref_surface(tegra_surface *surf) return VDP_STATUS_OK; } + pthread_mutex_lock(&surf->lock); if (surf->flags & SURFACE_OUTPUT) { shared_surface_kill_disp(surf); } - dynamic_release_surface_data(surf); unref_device(surf->dev); + pthread_mutex_unlock(&surf->lock); free(surf->frame); free(surf); diff --git a/src/surface_bitmap.c b/src/surface_bitmap.c index 86d4113..bcb0249 100644 --- a/src/surface_bitmap.c +++ b/src/surface_bitmap.c @@ -127,9 +127,12 @@ VdpStatus vdp_bitmap_surface_put_bits_native(VdpBitmapSurface surface, return VDP_STATUS_INVALID_HANDLE; } + pthread_mutex_lock(&surf->lock); + if (surf->flags & SURFACE_OUTPUT) { err = shared_surface_transfer_video(surf); if (err) { + pthread_mutex_unlock(&surf->lock); return err; } @@ -166,5 +169,7 @@ VdpStatus vdp_bitmap_surface_put_bits_native(VdpBitmapSurface surface, host1x_pixelbuffer_check_guard(surf->pixbuf); + pthread_mutex_unlock(&surf->lock); + return VDP_STATUS_OK; } diff --git a/src/surface_mixer.c b/src/surface_mixer.c index c6b68e7..20a02a7 100644 --- a/src/surface_mixer.c +++ b/src/surface_mixer.c @@ -203,6 +203,7 @@ VdpStatus vdp_video_mixer_create(VdpDevice device, tegra_device *dev = get_device(device); tegra_mixer *mix; VdpVideoMixer i; + int ret; if (dev == NULL) { return VDP_STATUS_INVALID_HANDLE; @@ -242,6 +243,14 @@ VdpStatus vdp_video_mixer_create(VdpDevice device, return VDP_STATUS_RESOURCES; } + ret = pthread_mutex_init(&mix->lock, NULL); + if (ret != 0) { + free(mix); + set_mixer(i, NULL); + ErrorMsg("pthread_mutex_init failed\n"); + return VDP_STATUS_RESOURCES; + } + ref_device(dev); mix->dev = dev; @@ -280,6 +289,8 @@ VdpStatus vdp_video_mixer_set_attribute_values( return VDP_STATUS_INVALID_HANDLE; } + pthread_mutex_lock(&mix->lock); + while (count--) { switch (attributes[count]) { case VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX: @@ -293,6 +304,8 @@ VdpStatus vdp_video_mixer_set_attribute_values( } } + pthread_mutex_unlock(&mix->lock); + return VDP_STATUS_OK; } @@ -409,6 +422,9 @@ VdpStatus vdp_video_mixer_render( return VDP_STATUS_INVALID_HANDLE; } + pthread_mutex_lock(&mix->lock); + pthread_mutex_lock(&dest_surf->lock); + shared_surface_kill_disp(dest_surf); if (destination_video_rect != NULL) { @@ -476,6 +492,8 @@ VdpStatus vdp_video_mixer_render( if (background_source_rect) { ret = dynamic_alloc_surface_data(dest_surf); if (ret) { + pthread_mutex_unlock(&dest_surf->lock); + pthread_mutex_unlock(&mix->lock); return VDP_STATUS_RESOURCES; } @@ -498,6 +516,8 @@ VdpStatus vdp_video_mixer_render( if (draw_background && bg_surf) { ret = dynamic_alloc_surface_data(dest_surf); if (ret) { + pthread_mutex_unlock(&dest_surf->lock); + pthread_mutex_unlock(&mix->lock); return VDP_STATUS_RESOURCES; } @@ -529,6 +549,8 @@ VdpStatus vdp_video_mixer_render( if (!shared) { ret = dynamic_alloc_surface_data(dest_surf); if (ret) { + pthread_mutex_unlock(&dest_surf->lock); + pthread_mutex_unlock(&mix->lock); return VDP_STATUS_RESOURCES; } @@ -562,6 +584,8 @@ VdpStatus vdp_video_mixer_render( while (layer_count--) { if (layers[layer_count].struct_version != VDP_LAYER_VERSION) { + pthread_mutex_unlock(&dest_surf->lock); + pthread_mutex_unlock(&mix->lock); return VDP_STATUS_INVALID_STRUCT_VERSION; } @@ -575,5 +599,8 @@ VdpStatus vdp_video_mixer_render( VDP_OUTPUT_SURFACE_RENDER_ROTATE_0); } + pthread_mutex_unlock(&dest_surf->lock); + pthread_mutex_unlock(&mix->lock); + return VDP_STATUS_OK; } diff --git a/src/surface_output.c b/src/surface_output.c index adb55c9..516061d 100644 --- a/src/surface_output.c +++ b/src/surface_output.c @@ -223,8 +223,11 @@ VdpStatus vdp_output_surface_render_bitmap_surface( src_surf = get_surface(source_surface); + pthread_mutex_lock(&src_surf->lock); + ret = shared_surface_transfer_video(dst_surf); if (ret) { + pthread_mutex_unlock(&src_surf->lock); return VDP_STATUS_RESOURCES; } @@ -255,6 +258,7 @@ VdpStatus vdp_output_surface_render_bitmap_surface( dst_x0, dst_y0, dst_width, dst_height); if (ret == 0) { + pthread_mutex_unlock(&src_surf->lock); return VDP_STATUS_OK; } @@ -267,11 +271,14 @@ VdpStatus vdp_output_surface_render_bitmap_surface( assert(ret != 0); + pthread_mutex_unlock(&src_surf->lock); + return VDP_STATUS_OK; } if (blend_state != NULL) { if (blend_state->struct_version != VDP_OUTPUT_SURFACE_RENDER_BLEND_STATE_VERSION) { + pthread_mutex_unlock(&src_surf->lock); return VDP_STATUS_INVALID_STRUCT_VERSION; } } @@ -320,6 +327,7 @@ VdpStatus vdp_output_surface_render_bitmap_surface( src_width, src_height, dst_x0, dst_y0, dst_width, dst_height); + pthread_mutex_unlock(&src_surf->lock); return VDP_STATUS_OK; } @@ -373,6 +381,8 @@ VdpStatus vdp_output_surface_render_bitmap_surface( assert(ret != 0); } + pthread_mutex_unlock(&src_surf->lock); + return VDP_STATUS_OK; } diff --git a/src/surface_shared.c b/src/surface_shared.c index 8a0d6ae..4e584ba 100644 --- a/src/surface_shared.c +++ b/src/surface_shared.c @@ -144,11 +144,13 @@ tegra_surface * shared_surface_swap_video(tegra_surface *old) assert(old->flags & SURFACE_VIDEO); + pthread_mutex_lock(&old->lock); pthread_mutex_lock(&shared_lock); shared = old->shared; pthread_mutex_unlock(&shared_lock); if (!shared) { + pthread_mutex_unlock(&old->lock); return old; } @@ -158,8 +160,10 @@ tegra_surface * shared_surface_swap_video(tegra_surface *old) replace_surface(old, new); pthread_mutex_unlock(&global_lock); + pthread_mutex_unlock(&old->lock); unref_surface(old); } else { + pthread_mutex_unlock(&old->lock); new = old; } @@ -183,15 +187,18 @@ int shared_surface_transfer_video(tegra_surface *disp) } pthread_mutex_unlock(&shared_lock); + pthread_mutex_lock(&disp->lock); ret = dynamic_alloc_surface_data(disp); if (ret) { if (shared) { goto unref; } + pthread_mutex_unlock(&disp->lock); return ret; } if (!shared) { + pthread_mutex_unlock(&disp->lock); return 0; } @@ -223,6 +230,7 @@ int shared_surface_transfer_video(tegra_surface *disp) shared->dst_width, shared->dst_height); unref: + pthread_mutex_unlock(&disp->lock); unref_surface(disp); unref_surface(video); unref_shared_surface(shared); @@ -237,6 +245,7 @@ void shared_surface_kill_disp(tegra_surface *disp) assert(disp->flags & SURFACE_OUTPUT); disp->data_dirty = false; + pthread_mutex_lock(&disp->lock); pthread_mutex_lock(&shared_lock); shared = disp->shared; @@ -253,4 +262,5 @@ void shared_surface_kill_disp(tegra_surface *disp) out: pthread_mutex_unlock(&shared_lock); + pthread_mutex_unlock(&disp->lock); } diff --git a/src/surface_video.c b/src/surface_video.c index 03b435f..9397314 100644 --- a/src/surface_video.c +++ b/src/surface_video.c @@ -133,10 +133,13 @@ VdpStatus vdp_video_surface_get_bits_y_cb_cr( assert(surf->flags & SURFACE_VIDEO); + pthread_mutex_lock(&surf->lock); + switch (destination_ycbcr_format) { case VDP_YCBCR_FORMAT_YV12: break; default: + pthread_mutex_unlock(&surf->lock); unref_surface(surf); return VDP_STATUS_NO_IMPLEMENTATION; } @@ -144,6 +147,7 @@ VdpStatus vdp_video_surface_get_bits_y_cb_cr( ret = sync_video_frame_dmabufs(surf, READ_START); if (ret) { + pthread_mutex_unlock(&surf->lock); unref_surface(surf); return ret; } @@ -181,12 +185,14 @@ VdpStatus vdp_video_surface_get_bits_y_cb_cr( ret = sync_video_frame_dmabufs(surf, READ_END); if (ret) { + pthread_mutex_unlock(&surf->lock); unref_surface(surf); return ret; } surf->flags &= ~SURFACE_DATA_NEEDS_SYNC; + pthread_mutex_unlock(&surf->lock); unref_surface(surf); return VDP_STATUS_OK; @@ -209,6 +215,8 @@ VdpStatus vdp_video_surface_put_bits_y_cb_cr( return VDP_STATUS_INVALID_HANDLE; } + assert(orig->flags & SURFACE_VIDEO); + switch (source_ycbcr_format) { case VDP_YCBCR_FORMAT_YV12: break; @@ -224,8 +232,6 @@ VdpStatus vdp_video_surface_put_bits_y_cb_cr( ref_surface(surf); } - assert(surf->flags & SURFACE_VIDEO); - ret = sync_video_frame_dmabufs(surf, WRITE_START); if (ret) { diff --git a/src/vdpau_tegra.h b/src/vdpau_tegra.h index 00bd1ea..b53bbfc 100644 --- a/src/vdpau_tegra.h +++ b/src/vdpau_tegra.h @@ -198,6 +198,7 @@ typedef struct tegra_decoder { typedef struct tegra_mixer { struct host1x_csc_params csc; + pthread_mutex_t lock; VdpColor bg_color; tegra_device *dev; bool custom_csc; |