mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-20 04:56:24 +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;
|
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
|
static void
|
||||||
gst_d3d11_device_release_swap_chain_internal (GstD3D11Device * device,
|
gst_d3d11_device_release_swap_chain_internal (GstD3D11Device * device,
|
||||||
IDXGISwapChain * swap_chain)
|
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,
|
IDXGISwapChain * gst_d3d11_device_create_swap_chain (GstD3D11Device * device,
|
||||||
const DXGI_SWAP_CHAIN_DESC * desc);
|
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,
|
void gst_d3d11_device_release_swap_chain (GstD3D11Device * device,
|
||||||
IDXGISwapChain * swap_chain);
|
IDXGISwapChain * swap_chain);
|
||||||
|
|
||||||
|
|
|
@ -1010,6 +1010,7 @@ gst_d3d11_window_prepare (GstD3D11Window * window, guint width, guint height,
|
||||||
GstCaps *render_caps;
|
GstCaps *render_caps;
|
||||||
MakeWindowAssociationData mwa_data = { 0, };
|
MakeWindowAssociationData mwa_data = { 0, };
|
||||||
UINT swapchain_flags = 0;
|
UINT swapchain_flags = 0;
|
||||||
|
DXGI_SWAP_EFFECT swap_effect = DXGI_SWAP_EFFECT_DISCARD;
|
||||||
#if (DXGI_HEADER_VERSION >= 5)
|
#if (DXGI_HEADER_VERSION >= 5)
|
||||||
gboolean have_cll = FALSE;
|
gboolean have_cll = FALSE;
|
||||||
gboolean have_mastering = 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");
|
GST_DEBUG_OBJECT (window, "DXGI 1.5 interface is available");
|
||||||
swapchain4_available = TRUE;
|
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);
|
g_object_get (window->device, "allow-tearing", &allow_tearing, NULL);
|
||||||
if (allow_tearing) {
|
if (allow_tearing) {
|
||||||
GST_DEBUG_OBJECT (window, "device support tearning");
|
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->width = width;
|
||||||
window->height = height;
|
window->height = height;
|
||||||
|
|
||||||
/* we will get client area at on_resize */
|
#if (DXGI_HEADER_VERSION >= 2)
|
||||||
desc.BufferDesc.Width = 0;
|
if (!window->swap_chain) {
|
||||||
desc.BufferDesc.Height = 0;
|
DXGI_SWAP_CHAIN_DESC1 desc1 = { 0, };
|
||||||
/* don't care refresh rate */
|
desc1.Width = 0;
|
||||||
desc.BufferDesc.RefreshRate.Numerator = 0;
|
desc1.Height = 0;
|
||||||
desc.BufferDesc.RefreshRate.Denominator = 1;
|
desc1.Format = window->render_format->dxgi_format;
|
||||||
desc.BufferDesc.Format = window->render_format->dxgi_format;
|
/* FIXME: add support stereo */
|
||||||
desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
|
desc1.Stereo = FALSE;
|
||||||
desc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
|
desc1.SampleDesc.Count = 1;
|
||||||
desc.SampleDesc.Count = 1;
|
desc1.SampleDesc.Quality = 0;
|
||||||
desc.SampleDesc.Quality = 0;
|
desc1.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||||
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
desc1.BufferCount = 2;
|
||||||
desc.BufferCount = 2;
|
/* NOTE: for UWP app, this should be DXGI_SCALING_ASPECT_RATIO_STRETCH
|
||||||
desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
* with CreateSwapChainForComposition or CreateSwapChainForCoreWindow */
|
||||||
#if (DXGI_HEADER_VERSION >= 5)
|
desc1.Scaling = DXGI_SCALING_STRETCH;
|
||||||
/* 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;
|
|
||||||
|
|
||||||
window->swap_chain =
|
/* scaling-stretch would break aspect-ratio so we prefer to use scaling-none,
|
||||||
gst_d3d11_device_create_swap_chain (window->device, &desc);
|
* 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) {
|
if (!window->swap_chain) {
|
||||||
GST_ERROR_OBJECT (window, "Cannot create swapchain");
|
GST_ERROR_OBJECT (window, "Cannot create swapchain");
|
||||||
|
|
Loading…
Reference in a new issue