mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-06 23:48:53 +00:00
d3d11window: Make use of partial presentation with IDXGISwapChain1::Present1
Since we might draw on partial area of backbuffer in case of force-aspect-ratio, presenting only updated area is more efficient way. See also https://docs.microsoft.com/ko-kr/windows/win32/direct3ddxgi/dxgi-1-2-presentation-improvements
This commit is contained in:
parent
487a41d312
commit
5298d95195
2 changed files with 42 additions and 27 deletions
|
@ -581,6 +581,7 @@ gst_d3d11_window_on_resize (GstD3D11Window * window, gboolean redraw)
|
||||||
D3D11_TEXTURE2D_DESC desc;
|
D3D11_TEXTURE2D_DESC desc;
|
||||||
DXGI_SWAP_CHAIN_DESC swap_desc;
|
DXGI_SWAP_CHAIN_DESC swap_desc;
|
||||||
ID3D11Texture2D *backbuffer = NULL;
|
ID3D11Texture2D *backbuffer = NULL;
|
||||||
|
GstVideoRectangle src_rect, dst_rect, rst_rect;
|
||||||
|
|
||||||
gst_d3d11_device_lock (window->device);
|
gst_d3d11_device_lock (window->device);
|
||||||
if (!window->swap_chain)
|
if (!window->swap_chain)
|
||||||
|
@ -618,8 +619,6 @@ gst_d3d11_window_on_resize (GstD3D11Window * window, gboolean redraw)
|
||||||
height = window->height;
|
height = window->height;
|
||||||
|
|
||||||
{
|
{
|
||||||
GstVideoRectangle src_rect, dst_rect;
|
|
||||||
|
|
||||||
src_rect.x = 0;
|
src_rect.x = 0;
|
||||||
src_rect.y = 0;
|
src_rect.y = 0;
|
||||||
src_rect.w = width * window->aspect_ratio_n;
|
src_rect.w = width * window->aspect_ratio_n;
|
||||||
|
@ -634,17 +633,20 @@ gst_d3d11_window_on_resize (GstD3D11Window * window, gboolean redraw)
|
||||||
src_rect.w = width * window->aspect_ratio_n;
|
src_rect.w = width * window->aspect_ratio_n;
|
||||||
src_rect.h = height * window->aspect_ratio_d;
|
src_rect.h = height * window->aspect_ratio_d;
|
||||||
|
|
||||||
gst_video_sink_center_rect (src_rect, dst_rect, &window->render_rect,
|
gst_video_sink_center_rect (src_rect, dst_rect, &rst_rect, TRUE);
|
||||||
TRUE);
|
|
||||||
} else {
|
} else {
|
||||||
window->render_rect = dst_rect;
|
rst_rect = dst_rect;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window->render_rect.left = rst_rect.x;
|
||||||
|
window->render_rect.top = rst_rect.y;
|
||||||
|
window->render_rect.right = rst_rect.x + rst_rect.w;
|
||||||
|
window->render_rect.bottom = rst_rect.y + rst_rect.h;
|
||||||
|
|
||||||
GST_LOG_OBJECT (window,
|
GST_LOG_OBJECT (window,
|
||||||
"New client area %dx%d, render rect x: %d, y: %d, %dx%d",
|
"New client area %dx%d, render rect x: %d, y: %d, %dx%d",
|
||||||
desc.Width, desc.Height, window->render_rect.x, window->render_rect.y,
|
desc.Width, desc.Height, rst_rect.x, rst_rect.y, rst_rect.w, rst_rect.h);
|
||||||
window->render_rect.w, window->render_rect.h);
|
|
||||||
|
|
||||||
hr = ID3D11Device_CreateRenderTargetView (d3d11_dev,
|
hr = ID3D11Device_CreateRenderTargetView (d3d11_dev,
|
||||||
(ID3D11Resource *) backbuffer, NULL, &window->rtv);
|
(ID3D11Resource *) backbuffer, NULL, &window->rtv);
|
||||||
|
@ -1126,7 +1128,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;
|
||||||
UINT swapchain_flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
|
UINT swapchain_flags = 0;
|
||||||
DXGI_SWAP_EFFECT swap_effect = DXGI_SWAP_EFFECT_DISCARD;
|
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;
|
||||||
|
@ -1215,6 +1217,7 @@ gst_d3d11_window_prepare (GstD3D11Window * window, guint width, guint height,
|
||||||
}
|
}
|
||||||
|
|
||||||
window->allow_tearing = FALSE;
|
window->allow_tearing = FALSE;
|
||||||
|
window->have_swapchain1 = FALSE;
|
||||||
#if (DXGI_HEADER_VERSION >= 5)
|
#if (DXGI_HEADER_VERSION >= 5)
|
||||||
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)) {
|
||||||
|
@ -1237,10 +1240,6 @@ 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");
|
||||||
|
@ -1259,10 +1258,10 @@ gst_d3d11_window_prepare (GstD3D11Window * window, guint width, guint height,
|
||||||
window->aspect_ratio_n = aspect_ratio_n;
|
window->aspect_ratio_n = aspect_ratio_n;
|
||||||
window->aspect_ratio_d = aspect_ratio_d;
|
window->aspect_ratio_d = aspect_ratio_d;
|
||||||
|
|
||||||
window->render_rect.x = 0;
|
window->render_rect.left = 0;
|
||||||
window->render_rect.y = 0;
|
window->render_rect.top = 0;
|
||||||
window->render_rect.w = width;
|
window->render_rect.right = width;
|
||||||
window->render_rect.h = height;
|
window->render_rect.bottom = height;
|
||||||
|
|
||||||
if (window->external_win_id) {
|
if (window->external_win_id) {
|
||||||
RECT client_rect = { 0, };
|
RECT client_rect = { 0, };
|
||||||
|
@ -1309,6 +1308,8 @@ gst_d3d11_window_prepare (GstD3D11Window * window, guint width, guint height,
|
||||||
|
|
||||||
if (!window->swap_chain) {
|
if (!window->swap_chain) {
|
||||||
GST_WARNING_OBJECT (window, "Failed to create swapchain1");
|
GST_WARNING_OBJECT (window, "Failed to create swapchain1");
|
||||||
|
} else {
|
||||||
|
window->have_swapchain1 = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1503,15 +1504,10 @@ gst_d3d111_window_present (GstD3D11Window * self, GstBuffer * buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->first_present) {
|
if (self->first_present) {
|
||||||
RECT rect;
|
gst_d3d11_color_converter_update_rect (self->converter,
|
||||||
|
&self->render_rect);
|
||||||
rect.left = self->render_rect.x;
|
gst_d3d11_overlay_compositor_update_rect (self->compositor,
|
||||||
rect.right = self->render_rect.x + self->render_rect.w;
|
&self->render_rect);
|
||||||
rect.top = self->render_rect.y;
|
|
||||||
rect.bottom = self->render_rect.y + self->render_rect.h;
|
|
||||||
|
|
||||||
gst_d3d11_color_converter_update_rect (self->converter, &rect);
|
|
||||||
gst_d3d11_overlay_compositor_update_rect (self->compositor, &rect);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_d3d11_color_converter_convert_unlocked (self->converter,
|
gst_d3d11_color_converter_convert_unlocked (self->converter,
|
||||||
|
@ -1526,7 +1522,25 @@ gst_d3d111_window_present (GstD3D11Window * self, GstBuffer * buffer)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if (DXGI_HEADER_VERSION >= 2)
|
||||||
|
if (self->have_swapchain1) {
|
||||||
|
DXGI_PRESENT_PARAMETERS present_params = { 0, };
|
||||||
|
if (self->first_present) {
|
||||||
|
/* the first present should not specify dirty-rect */
|
||||||
|
hr = IDXGISwapChain1_Present1 ((IDXGISwapChain1 *) self->swap_chain,
|
||||||
|
0, present_flags, &present_params);
|
||||||
|
} else {
|
||||||
|
present_params.DirtyRectsCount = 1;
|
||||||
|
present_params.pDirtyRects = &self->render_rect;
|
||||||
|
hr = IDXGISwapChain1_Present1 ((IDXGISwapChain1 *) self->swap_chain,
|
||||||
|
0, present_flags, &present_params);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
hr = IDXGISwapChain_Present (self->swap_chain, 0, present_flags);
|
hr = IDXGISwapChain_Present (self->swap_chain, 0, present_flags);
|
||||||
|
}
|
||||||
|
|
||||||
self->first_present = FALSE;
|
self->first_present = FALSE;
|
||||||
|
|
||||||
if (!gst_d3d11_result (hr, self->device)) {
|
if (!gst_d3d11_result (hr, self->device)) {
|
||||||
|
|
|
@ -73,7 +73,7 @@ struct _GstD3D11Window
|
||||||
GstVideoContentLightLevel content_light_level;
|
GstVideoContentLightLevel content_light_level;
|
||||||
|
|
||||||
/* calculated rect with aspect ratio and window area */
|
/* calculated rect with aspect ratio and window area */
|
||||||
GstVideoRectangle render_rect;
|
RECT render_rect;
|
||||||
|
|
||||||
/* requested rect via gst_d3d11_window_render */
|
/* requested rect via gst_d3d11_window_render */
|
||||||
GstVideoRectangle rect;
|
GstVideoRectangle rect;
|
||||||
|
@ -111,6 +111,7 @@ struct _GstD3D11Window
|
||||||
ID3D11RenderTargetView *rtv;
|
ID3D11RenderTargetView *rtv;
|
||||||
DXGI_FORMAT format;
|
DXGI_FORMAT format;
|
||||||
gboolean first_present;
|
gboolean first_present;
|
||||||
|
gboolean have_swapchain1;
|
||||||
|
|
||||||
GstD3D11Device *device;
|
GstD3D11Device *device;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue