mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-10 17:35:59 +00:00
dwrite: Protect entire draw operation with D3D11 lock
d2d runtime seems to execute pending GPU command list when DXGI ID2D1RenderTarget is being released, and it will invoke d3d11 immediate context APIs. Should protect all rendering operations and DXGI resources with lock. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5659>
This commit is contained in:
parent
4037334143
commit
ac11ccd4ff
1 changed files with 14 additions and 10 deletions
|
@ -1128,10 +1128,8 @@ gst_dwrite_overlay_object_draw_layout (GstDWriteOverlayObject * self,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
gst_d3d11_device_lock (priv->device);
|
||||
if (!gst_dwrite_overlay_object_get_target_from_d3d11 (self, mem, &target)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't get target from texture");
|
||||
gst_d3d11_device_unlock (priv->device);
|
||||
gst_memory_unmap (mem, &info);
|
||||
gst_clear_buffer (&priv->layout_buf);
|
||||
return FALSE;
|
||||
|
@ -1144,10 +1142,13 @@ gst_dwrite_overlay_object_draw_layout (GstDWriteOverlayObject * self,
|
|||
D2D1::Rect (0, 0, width, height), layout, target.Get ());
|
||||
target->EndDraw ();
|
||||
|
||||
if (!priv->use_bitmap) {
|
||||
gst_d3d11_device_unlock (priv->device);
|
||||
/* Release render target before unmapping. Otherwise pending GPU operations
|
||||
* can be executed after releasing keyed-mutex, if texture was allocated with
|
||||
* keyed-mutex enabled */
|
||||
target = nullptr;
|
||||
|
||||
if (!priv->use_bitmap)
|
||||
gst_memory_unmap (mem, &info);
|
||||
}
|
||||
|
||||
priv->overlay_rect = gst_video_overlay_rectangle_new_raw (priv->layout_buf,
|
||||
x, y, width, height, GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA);
|
||||
|
@ -1245,7 +1246,6 @@ gst_dwrite_overlay_mode_convert (GstDWriteOverlayObject * self,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
gst_d3d11_device_lock (priv->device);
|
||||
if (!gst_d3d11_converter_convert_buffer_unlocked (priv->pre_conv,
|
||||
buffer, pre_buf)) {
|
||||
GST_ERROR_OBJECT (self, "pre-convert failed");
|
||||
|
@ -1264,13 +1264,11 @@ gst_dwrite_overlay_mode_convert (GstDWriteOverlayObject * self,
|
|||
goto error;
|
||||
}
|
||||
|
||||
gst_d3d11_device_unlock (priv->device);
|
||||
gst_buffer_unref (pre_buf);
|
||||
|
||||
return TRUE;
|
||||
|
||||
error:
|
||||
gst_d3d11_device_unlock (priv->device);
|
||||
gst_clear_buffer (&pre_buf);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -1282,8 +1280,11 @@ gst_dwrite_overlay_object_draw (GstDWriteOverlayObject * object,
|
|||
GstDWriteOverlayObjectPrivate *priv = object->priv;
|
||||
gboolean ret = FALSE;
|
||||
|
||||
if (priv->device)
|
||||
gst_d3d11_device_lock (priv->device);
|
||||
|
||||
if (!gst_dwrite_overlay_object_draw_layout (object, layout, x, y))
|
||||
return FALSE;
|
||||
goto out;
|
||||
|
||||
switch (priv->blend_mode) {
|
||||
case GstDWriteBlendMode::ATTACH_TEXTURE:
|
||||
|
@ -1302,8 +1303,11 @@ gst_dwrite_overlay_object_draw (GstDWriteOverlayObject * object,
|
|||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
if (priv->device)
|
||||
gst_d3d11_device_unlock (priv->device);
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue