From: Seungha Yang Date: Wed, 18 Dec 2019 05:23:03 +0000 (+0900) Subject: d3d11window: Use CreateSwapChainForHwnd if available X-Git-Tag: 1.19.3~507^2~2512 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=32d618c6772978d1ebaaa0e1456965eaebed214c;p=platform%2Fupstream%2Fgstreamer.git d3d11window: Use CreateSwapChainForHwnd if available That's recommended way from MS and CreateSwapChainForHwnd supports more options than CreateSwapChain --- diff --git a/sys/d3d11/gstd3d11device.c b/sys/d3d11/gstd3d11device.c index 05d3d60..02f0cc3 100644 --- a/sys/d3d11/gstd3d11device.c +++ b/sys/d3d11/gstd3d11device.c @@ -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) diff --git a/sys/d3d11/gstd3d11device.h b/sys/d3d11/gstd3d11device.h index ee1dc58..59cb647 100644 --- a/sys/d3d11/gstd3d11device.h +++ b/sys/d3d11/gstd3d11device.h @@ -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); diff --git a/sys/d3d11/gstd3d11window.c b/sys/d3d11/gstd3d11window.c index 33b14b8..047656a 100644 --- a/sys/d3d11/gstd3d11window.c +++ b/sys/d3d11/gstd3d11window.c @@ -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; +#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; + + /* 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 - 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) { + /* 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");