summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Osipenko <digetx@gmail.com>2017-12-27 21:00:55 +0300
committerDmitry Osipenko <digetx@gmail.com>2017-12-28 16:38:27 +0300
commit3fbb7186859307f8a5508d89a7c16e216b814747 (patch)
tree59a89a8937cacb367ebdcc05644898ec04931dea
parentb7e346b4465ce70bfd8b53b11d1c2fd8e62614a8 (diff)
Harden lockings
-rw-r--r--src/presentation_queue.c2
-rw-r--r--src/surface.c20
-rw-r--r--src/surface_bitmap.c5
-rw-r--r--src/surface_mixer.c27
-rw-r--r--src/surface_output.c10
-rw-r--r--src/surface_shared.c10
-rw-r--r--src/surface_video.c10
-rw-r--r--src/vdpau_tegra.h1
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;