mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
d3d11window: Use CreateSwapChainForHwnd if available
That's recommended way from MS and CreateSwapChainForHwnd supports more options than CreateSwapChain
This commit is contained in:
parent
9fd0b62f2d
commit
32d618c677
3 changed files with 135 additions and 25 deletions
|
@ -783,6 +783,72 @@ gst_d3d11_device_create_swap_chain (GstD3D11Device * device,
|
|||
return data.swap_chain;
|
||||
}
|
||||
|
||||
#if (DXGI_HEADER_VERSION >= 2)
|
||||
typedef struct
|
||||
{
|
||||
IDXGISwapChain1 *swap_chain;
|
||||
HWND hwnd;
|
||||
const DXGI_SWAP_CHAIN_DESC1 *desc;
|
||||
const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *fullscreen_desc;
|
||||
IDXGIOutput *output;
|
||||
} CreateSwapChainForHwndData;
|
||||
|
||||
static void
|
||||
gst_d3d11_device_create_swap_chain_for_hwnd_internal (GstD3D11Device * device,
|
||||
CreateSwapChainForHwndData * data)
|
||||
{
|
||||
GstD3D11DevicePrivate *priv = device->priv;
|
||||
HRESULT hr;
|
||||
|
||||
hr = IDXGIFactory2_CreateSwapChainForHwnd ((IDXGIFactory2 *) priv->factory,
|
||||
(IUnknown *) priv->device, data->hwnd, data->desc, data->fullscreen_desc,
|
||||
data->output, &data->swap_chain);
|
||||
|
||||
if (!gst_d3d11_result (hr)) {
|
||||
GST_ERROR_OBJECT (device, "Cannot create SwapChain Object: 0x%x",
|
||||
(guint) hr);
|
||||
data->swap_chain = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_d3d11_device_create_swap_chain_for_hwnd:
|
||||
* @device: a #GstD3D11Device
|
||||
* @hwnd: HWND handle
|
||||
* @desc: a DXGI_SWAP_CHAIN_DESC1 structure for swapchain
|
||||
* @fullscreen_desc: (nullable): a DXGI_SWAP_CHAIN_FULLSCREEN_DESC
|
||||
* structure for swapchain
|
||||
* @output: (nullable): a IDXGIOutput interface for the output to restrict content to
|
||||
*
|
||||
* Create a IDXGISwapChain1 object. Caller must release returned swap chain object
|
||||
* via IDXGISwapChain1_Release()
|
||||
*
|
||||
* Returns: (transfer full) (nullable): a new IDXGISwapChain1 or %NULL
|
||||
* when failed to create swap chain with given @desc
|
||||
*/
|
||||
IDXGISwapChain1 *
|
||||
gst_d3d11_device_create_swap_chain_for_hwnd (GstD3D11Device * device,
|
||||
HWND hwnd, const DXGI_SWAP_CHAIN_DESC1 * desc,
|
||||
const DXGI_SWAP_CHAIN_FULLSCREEN_DESC * fullscreen_desc,
|
||||
IDXGIOutput * output)
|
||||
{
|
||||
CreateSwapChainForHwndData data = { 0, };
|
||||
|
||||
g_return_val_if_fail (GST_IS_D3D11_DEVICE (device), NULL);
|
||||
|
||||
data.swap_chain = NULL;
|
||||
data.hwnd = hwnd;
|
||||
data.desc = desc;
|
||||
data.fullscreen_desc = fullscreen_desc;
|
||||
data.output = output;
|
||||
|
||||
gst_d3d11_device_thread_add (device, (GstD3D11DeviceThreadFunc)
|
||||
gst_d3d11_device_create_swap_chain_for_hwnd_internal, &data);
|
||||
|
||||
return data.swap_chain;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
gst_d3d11_device_release_swap_chain_internal (GstD3D11Device * device,
|
||||
IDXGISwapChain * swap_chain)
|
||||
|
|
|
@ -90,6 +90,14 @@ D3D_FEATURE_LEVEL gst_d3d11_device_get_chosen_feature_level (GstD3D11Device
|
|||
IDXGISwapChain * gst_d3d11_device_create_swap_chain (GstD3D11Device * device,
|
||||
const DXGI_SWAP_CHAIN_DESC * desc);
|
||||
|
||||
#if (DXGI_HEADER_VERSION >= 2)
|
||||
IDXGISwapChain1 * gst_d3d11_device_create_swap_chain_for_hwnd (GstD3D11Device * device,
|
||||
HWND hwnd,
|
||||
const DXGI_SWAP_CHAIN_DESC1 * desc,
|
||||
const DXGI_SWAP_CHAIN_FULLSCREEN_DESC * fullscreen_desc,
|
||||
IDXGIOutput * output);
|
||||
#endif
|
||||
|
||||
void gst_d3d11_device_release_swap_chain (GstD3D11Device * device,
|
||||
IDXGISwapChain * swap_chain);
|
||||
|
||||
|
|
|
@ -1010,6 +1010,7 @@ gst_d3d11_window_prepare (GstD3D11Window * window, guint width, guint height,
|
|||
GstCaps *render_caps;
|
||||
MakeWindowAssociationData mwa_data = { 0, };
|
||||
UINT swapchain_flags = 0;
|
||||
DXGI_SWAP_EFFECT swap_effect = DXGI_SWAP_EFFECT_DISCARD;
|
||||
#if (DXGI_HEADER_VERSION >= 5)
|
||||
gboolean have_cll = FALSE;
|
||||
gboolean have_mastering = FALSE;
|
||||
|
@ -1099,6 +1100,10 @@ gst_d3d11_window_prepare (GstD3D11Window * window, guint width, guint height,
|
|||
GST_DEBUG_OBJECT (window, "DXGI 1.5 interface is available");
|
||||
swapchain4_available = TRUE;
|
||||
|
||||
/* For non-DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709 color space support,
|
||||
* DXGI_SWAP_EFFECT_FLIP_DISCARD instead of DXGI_SWAP_EFFECT_DISCARD */
|
||||
swap_effect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||
|
||||
g_object_get (window->device, "allow-tearing", &allow_tearing, NULL);
|
||||
if (allow_tearing) {
|
||||
GST_DEBUG_OBJECT (window, "device support tearning");
|
||||
|
@ -1135,32 +1140,63 @@ gst_d3d11_window_prepare (GstD3D11Window * window, guint width, guint height,
|
|||
window->width = width;
|
||||
window->height = height;
|
||||
|
||||
/* we will get client area at on_resize */
|
||||
desc.BufferDesc.Width = 0;
|
||||
desc.BufferDesc.Height = 0;
|
||||
/* don't care refresh rate */
|
||||
desc.BufferDesc.RefreshRate.Numerator = 0;
|
||||
desc.BufferDesc.RefreshRate.Denominator = 1;
|
||||
desc.BufferDesc.Format = window->render_format->dxgi_format;
|
||||
desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
|
||||
desc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.SampleDesc.Quality = 0;
|
||||
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
desc.BufferCount = 2;
|
||||
desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
||||
#if (DXGI_HEADER_VERSION >= 5)
|
||||
/* For non-DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709 color space support,
|
||||
* DXGI_SWAP_EFFECT_FLIP_DISCARD instead of DXGI_SWAP_EFFECT_DISCARD */
|
||||
if (swapchain4_available)
|
||||
desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||
#endif
|
||||
desc.OutputWindow = window->internal_win_id;
|
||||
desc.Windowed = TRUE;
|
||||
desc.Flags = swapchain_flags;
|
||||
#if (DXGI_HEADER_VERSION >= 2)
|
||||
if (!window->swap_chain) {
|
||||
DXGI_SWAP_CHAIN_DESC1 desc1 = { 0, };
|
||||
desc1.Width = 0;
|
||||
desc1.Height = 0;
|
||||
desc1.Format = window->render_format->dxgi_format;
|
||||
/* FIXME: add support stereo */
|
||||
desc1.Stereo = FALSE;
|
||||
desc1.SampleDesc.Count = 1;
|
||||
desc1.SampleDesc.Quality = 0;
|
||||
desc1.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
desc1.BufferCount = 2;
|
||||
/* NOTE: for UWP app, this should be DXGI_SCALING_ASPECT_RATIO_STRETCH
|
||||
* with CreateSwapChainForComposition or CreateSwapChainForCoreWindow */
|
||||
desc1.Scaling = DXGI_SCALING_STRETCH;
|
||||
|
||||
window->swap_chain =
|
||||
gst_d3d11_device_create_swap_chain (window->device, &desc);
|
||||
/* scaling-stretch would break aspect-ratio so we prefer to use scaling-none,
|
||||
* but Windows7 does not support this method */
|
||||
if (gst_d3d11_is_windows_8_or_greater ())
|
||||
desc1.Scaling = DXGI_SCALING_NONE;
|
||||
desc1.SwapEffect = swap_effect;
|
||||
/* FIXME: might need to define for ovelay composition */
|
||||
desc1.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
|
||||
desc1.Flags = swapchain_flags;
|
||||
|
||||
window->swap_chain = (IDXGISwapChain *)
|
||||
gst_d3d11_device_create_swap_chain_for_hwnd (window->device,
|
||||
window->internal_win_id, &desc1, NULL, NULL);
|
||||
|
||||
if (!window->swap_chain) {
|
||||
GST_WARNING_OBJECT (window, "Failed to create swapchain1");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!window->swap_chain) {
|
||||
/* we will get client area at on_resize */
|
||||
desc.BufferDesc.Width = 0;
|
||||
desc.BufferDesc.Height = 0;
|
||||
/* don't care refresh rate */
|
||||
desc.BufferDesc.RefreshRate.Numerator = 0;
|
||||
desc.BufferDesc.RefreshRate.Denominator = 1;
|
||||
desc.BufferDesc.Format = window->render_format->dxgi_format;
|
||||
desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
|
||||
desc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.SampleDesc.Quality = 0;
|
||||
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
desc.BufferCount = 2;
|
||||
desc.SwapEffect = swap_effect;
|
||||
desc.OutputWindow = window->internal_win_id;
|
||||
desc.Windowed = TRUE;
|
||||
desc.Flags = swapchain_flags;
|
||||
|
||||
window->swap_chain =
|
||||
gst_d3d11_device_create_swap_chain (window->device, &desc);
|
||||
}
|
||||
|
||||
if (!window->swap_chain) {
|
||||
GST_ERROR_OBJECT (window, "Cannot create swapchain");
|
||||
|
|
Loading…
Reference in a new issue