d3d11window: Use allow-tearing mode if device supports it

As the recommendation from MS.
This commit is contained in:
Seungha Yang 2019-12-17 13:47:24 +09:00
parent 72b6b3557d
commit 23b47a7ec1
3 changed files with 41 additions and 2 deletions

View file

@ -52,6 +52,7 @@ enum
PROP_VENDER_ID, PROP_VENDER_ID,
PROP_HARDWARE, PROP_HARDWARE,
PROP_DESCRIPTION, PROP_DESCRIPTION,
PROP_ALLOW_TEARING,
}; };
#define DEFAULT_ADAPTER 0 #define DEFAULT_ADAPTER 0
@ -63,6 +64,7 @@ struct _GstD3D11DevicePrivate
guint vender_id; guint vender_id;
gboolean hardware; gboolean hardware;
gchar *description; gchar *description;
gboolean allow_tearing;
ID3D11Device *device; ID3D11Device *device;
ID3D11DeviceContext *device_context; ID3D11DeviceContext *device_context;
@ -186,6 +188,11 @@ gst_d3d11_device_class_init (GstD3D11DeviceClass * klass)
"Human readable device description", NULL, "Human readable device description", NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_ALLOW_TEARING,
g_param_spec_boolean ("allow-tearing", "Allow tearing",
"Whether dxgi device supports allow-tearing feature or not", FALSE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
GST_DEBUG_CATEGORY_GET (GST_CAT_CONTEXT, "GST_CONTEXT"); GST_DEBUG_CATEGORY_GET (GST_CAT_CONTEXT, "GST_CONTEXT");
} }
@ -232,6 +239,16 @@ gst_d3d11_device_constructed (GObject * object)
if (!gst_d3d11_result (hr)) { if (!gst_d3d11_result (hr)) {
GST_INFO_OBJECT (self, "IDXGIFactory5 was unavailable"); GST_INFO_OBJECT (self, "IDXGIFactory5 was unavailable");
factory = NULL; factory = NULL;
} else {
BOOL allow_tearing;
hr = IDXGIFactory5_CheckFeatureSupport ((IDXGIFactory5 *) factory,
DXGI_FEATURE_PRESENT_ALLOW_TEARING, (void *) &allow_tearing,
sizeof (allow_tearing));
priv->allow_tearing = SUCCEEDED (hr) && allow_tearing;
hr = S_OK;
} }
priv->factory_ver = GST_D3D11_DXGI_FACTORY_5; priv->factory_ver = GST_D3D11_DXGI_FACTORY_5;
@ -409,6 +426,9 @@ gst_d3d11_device_get_property (GObject * object, guint prop_id,
case PROP_DESCRIPTION: case PROP_DESCRIPTION:
g_value_set_string (value, priv->description); g_value_set_string (value, priv->description);
break; break;
case PROP_ALLOW_TEARING:
g_value_set_boolean (value, priv->allow_tearing);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;

View file

@ -1007,6 +1007,7 @@ gst_d3d11_window_prepare (GstD3D11Window * window, guint width, guint height,
DXGI_SWAP_CHAIN_DESC desc = { 0, }; DXGI_SWAP_CHAIN_DESC desc = { 0, };
GstCaps *render_caps; GstCaps *render_caps;
MakeWindowAssociationData mwa_data = { 0, }; MakeWindowAssociationData mwa_data = { 0, };
UINT swapchain_flags = 0;
#if defined(HAVE_DXGI_1_5_H) #if defined(HAVE_DXGI_1_5_H)
gboolean have_cll = FALSE; gboolean have_cll = FALSE;
gboolean have_mastering = FALSE; gboolean have_mastering = FALSE;
@ -1072,6 +1073,8 @@ gst_d3d11_window_prepare (GstD3D11Window * window, guint width, guint height,
return FALSE; return FALSE;
} }
window->allow_tearing = FALSE;
#if defined(HAVE_DXGI_1_5_H) #if defined(HAVE_DXGI_1_5_H)
if (!gst_video_content_light_level_from_caps (&window->content_light_level, if (!gst_video_content_light_level_from_caps (&window->content_light_level,
caps)) { caps)) {
@ -1089,8 +1092,17 @@ gst_d3d11_window_prepare (GstD3D11Window * window, guint width, guint height,
if (gst_d3d11_device_get_chosen_dxgi_factory_version (window->device) >= if (gst_d3d11_device_get_chosen_dxgi_factory_version (window->device) >=
GST_D3D11_DXGI_FACTORY_5) { GST_D3D11_DXGI_FACTORY_5) {
gboolean allow_tearing = FALSE;
GST_DEBUG_OBJECT (window, "DXGI 1.5 interface is available"); GST_DEBUG_OBJECT (window, "DXGI 1.5 interface is available");
swapchain4_available = TRUE; swapchain4_available = TRUE;
g_object_get (window->device, "allow-tearing", &allow_tearing, NULL);
if (allow_tearing) {
GST_DEBUG_OBJECT (window, "device support tearning");
swapchain_flags |= DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING;
window->allow_tearing = TRUE;
}
} }
#endif #endif
@ -1143,7 +1155,7 @@ gst_d3d11_window_prepare (GstD3D11Window * window, guint width, guint height,
#endif #endif
desc.OutputWindow = window->internal_win_id; desc.OutputWindow = window->internal_win_id;
desc.Windowed = TRUE; desc.Windowed = TRUE;
desc.Flags = 0; desc.Flags = swapchain_flags;
window->swap_chain = window->swap_chain =
gst_d3d11_device_create_swap_chain (window->device, &desc); gst_d3d11_device_create_swap_chain (window->device, &desc);
@ -1307,6 +1319,7 @@ _present_on_device_thread (GstD3D11Device * device, FramePresentData * data)
GstD3D11Window *self = data->window; GstD3D11Window *self = data->window;
ID3D11DeviceContext *device_context; ID3D11DeviceContext *device_context;
HRESULT hr; HRESULT hr;
UINT present_flags = DXGI_PRESENT_DO_NOT_WAIT;
device_context = gst_d3d11_device_get_device_context_handle (device); device_context = gst_d3d11_device_get_device_context_handle (device);
gst_buffer_replace (&self->cached_buffer, data->buffer); gst_buffer_replace (&self->cached_buffer, data->buffer);
@ -1333,8 +1346,13 @@ _present_on_device_thread (GstD3D11Device * device, FramePresentData * data)
gst_d3d11_color_converter_update_rect (self->converter, &rect); gst_d3d11_color_converter_update_rect (self->converter, &rect);
gst_d3d11_color_converter_convert (self->converter, srv, &self->rtv); gst_d3d11_color_converter_convert (self->converter, srv, &self->rtv);
} }
#ifdef HAVE_DXGI_1_5_H
if (self->allow_tearing) {
present_flags |= DXGI_PRESENT_ALLOW_TEARING;
}
#endif
hr = IDXGISwapChain_Present (self->swap_chain, 0, DXGI_PRESENT_DO_NOT_WAIT); hr = IDXGISwapChain_Present (self->swap_chain, 0, present_flags);
if (!gst_d3d11_result (hr)) { if (!gst_d3d11_result (hr)) {
GST_WARNING_OBJECT (self, "Direct3D cannot present texture, hr: 0x%x", GST_WARNING_OBJECT (self, "Direct3D cannot present texture, hr: 0x%x",

View file

@ -108,6 +108,7 @@ struct _GstD3D11Window
gboolean enable_navigation_events; gboolean enable_navigation_events;
GstBuffer *cached_buffer; GstBuffer *cached_buffer;
gboolean allow_tearing;
}; };
struct _GstD3D11WindowClass struct _GstD3D11WindowClass