d3d11videosink: Add redraw-on-update property

If users update geometry related properties very frequently
for a stream to be animated, redrawing on every update
can make rendering choppy or can be a performance bottleneck.
To address the issue, adding a property to control the behavior
of redrawing scene when geometry related properties are updated.

Also, do not resize swapchain on such property update, since
re-allocating backbuffer and multi-sampled render target is
unnecessary in that case.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5575>
This commit is contained in:
Seungha Yang 2023-10-29 23:43:56 +09:00 committed by GStreamer Marge Bot
parent 443f205c38
commit 107edc0c07
4 changed files with 53 additions and 14 deletions

View file

@ -10406,6 +10406,18 @@
"type": "GstVideoPrimariesMode", "type": "GstVideoPrimariesMode",
"writable": true "writable": true
}, },
"redraw-on-update": {
"blurb": "Immediately apply updated geometry related properties and redraw. If disabled, properties will be applied on the next frame or window resize",
"conditionally-available": false,
"construct": false,
"construct-only": false,
"controllable": false,
"default": "true",
"mutable": "null",
"readable": true,
"type": "gboolean",
"writable": true
},
"render-rectangle": { "render-rectangle": {
"blurb": "The render rectangle ('<x, y, width, height>')", "blurb": "The render rectangle ('<x, y, width, height>')",
"conditionally-available": false, "conditionally-available": false,

View file

@ -74,6 +74,7 @@ enum
PROP_SCALE_Y, PROP_SCALE_Y,
PROP_MSAA, PROP_MSAA,
PROP_SAMPLING_METHOD, PROP_SAMPLING_METHOD,
PROP_REDRAW_ON_UPDATE,
PROP_RENDER_RECTANGE, PROP_RENDER_RECTANGE,
}; };
@ -93,6 +94,7 @@ enum
#define DEFAULT_ORTHO FALSE #define DEFAULT_ORTHO FALSE
#define DEFAULT_MSAA GST_D3D11_MSAA_DISABLED #define DEFAULT_MSAA GST_D3D11_MSAA_DISABLED
#define DEFAULT_SAMPLING_METHOD GST_D3D11_SAMPLING_METHOD_BILINEAR #define DEFAULT_SAMPLING_METHOD GST_D3D11_SAMPLING_METHOD_BILINEAR
#define DEFAULT_REDROW_ON_UPDATE TRUE
/** /**
* GstD3D11VideoSinkDisplayFormat: * GstD3D11VideoSinkDisplayFormat:
@ -212,6 +214,7 @@ struct _GstD3D11VideoSink
gfloat scale_y; gfloat scale_y;
GstD3D11MSAAMode msaa; GstD3D11MSAAMode msaa;
GstD3D11SamplingMethod sampling_method; GstD3D11SamplingMethod sampling_method;
gboolean redraw_on_update;
/* saved render rectangle until we have a window */ /* saved render rectangle until we have a window */
GstVideoRectangle render_rect; GstVideoRectangle render_rect;
@ -539,6 +542,21 @@ gst_d3d11_video_sink_class_init (GstD3D11VideoSinkClass * klass)
DEFAULT_SAMPLING_METHOD, (GParamFlags) (GST_PARAM_MUTABLE_READY | DEFAULT_SAMPLING_METHOD, (GParamFlags) (GST_PARAM_MUTABLE_READY |
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
/**
* GstD3D11VideoSink:redraw-on-update:
*
* Immediately apply updated geometry related properties and redraw
*
* Since: 1.24
*/
g_object_class_install_property (gobject_class, PROP_REDRAW_ON_UPDATE,
g_param_spec_boolean ("redraw-on-update",
"redraw-on-update",
"Immediately apply updated geometry related properties and redraw. "
"If disabled, properties will be applied on the next frame or "
"window resize", DEFAULT_REDROW_ON_UPDATE,
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
/** /**
* GstD3D11VideoSink:render-rectangle: * GstD3D11VideoSink:render-rectangle:
* *
@ -668,6 +686,7 @@ gst_d3d11_video_sink_init (GstD3D11VideoSink * self)
self->scale_y = DEFAULT_SCALE; self->scale_y = DEFAULT_SCALE;
self->msaa = DEFAULT_MSAA; self->msaa = DEFAULT_MSAA;
self->sampling_method = DEFAULT_SAMPLING_METHOD; self->sampling_method = DEFAULT_SAMPLING_METHOD;
self->redraw_on_update = DEFAULT_REDROW_ON_UPDATE;
InitializeCriticalSection (&self->lock); InitializeCriticalSection (&self->lock);
} }
@ -765,6 +784,9 @@ gst_d3d11_videosink_set_property (GObject * object, guint prop_id,
case PROP_SAMPLING_METHOD: case PROP_SAMPLING_METHOD:
self->sampling_method = (GstD3D11SamplingMethod) g_value_get_enum (value); self->sampling_method = (GstD3D11SamplingMethod) g_value_get_enum (value);
break; break;
case PROP_REDRAW_ON_UPDATE:
self->redraw_on_update = g_value_get_boolean (value);
break;
case PROP_RENDER_RECTANGE: case PROP_RENDER_RECTANGE:
gst_video_overlay_set_property (object, PROP_RENDER_RECTANGE, gst_video_overlay_set_property (object, PROP_RENDER_RECTANGE,
PROP_RENDER_RECTANGE, value); PROP_RENDER_RECTANGE, value);
@ -847,6 +869,9 @@ gst_d3d11_videosink_get_property (GObject * object, guint prop_id,
case PROP_SAMPLING_METHOD: case PROP_SAMPLING_METHOD:
g_value_set_enum (value, self->sampling_method); g_value_set_enum (value, self->sampling_method);
break; break;
case PROP_REDRAW_ON_UPDATE:
g_value_set_boolean (value, self->redraw_on_update);
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;
@ -1272,7 +1297,8 @@ done:
"enable-navigation-events", self->enable_navigation_events, "enable-navigation-events", self->enable_navigation_events,
"emit-present", self->emit_present, nullptr); "emit-present", self->emit_present, nullptr);
gst_d3d11_window_set_orientation (self->window, self->selected_method, gst_d3d11_window_set_orientation (self->window, self->redraw_on_update,
self->selected_method,
self->fov, self->ortho, self->rotation_x, self->rotation_y, self->fov, self->ortho, self->rotation_x, self->rotation_y,
self->rotation_z, self->scale_x, self->scale_y); self->rotation_z, self->scale_x, self->scale_y);
gst_d3d11_window_set_msaa_mode (self->window, self->msaa); gst_d3d11_window_set_msaa_mode (self->window, self->msaa);
@ -1540,7 +1566,8 @@ gst_d3d11_video_sink_set_orientation (GstD3D11VideoSink * self,
} }
if (self->window) { if (self->window) {
gst_d3d11_window_set_orientation (self->window, self->selected_method, gst_d3d11_window_set_orientation (self->window, self->redraw_on_update,
self->selected_method,
self->fov, self->ortho, self->rotation_x, self->rotation_y, self->fov, self->ortho, self->rotation_x, self->rotation_y,
self->rotation_z, self->scale_x, self->scale_y); self->rotation_z, self->scale_x, self->scale_y);
} }

View file

@ -953,7 +953,7 @@ gst_d3d11_window_present (GstD3D11Window * self, GstBuffer * buffer,
/* We use flip mode swapchain and will not redraw borders. /* We use flip mode swapchain and will not redraw borders.
* So backbuffer should be cleared manually in order to remove artifact of * So backbuffer should be cleared manually in order to remove artifact of
* previous client's rendering on present signal */ * previous client's rendering on present signal */
if (self->emit_present) { if (self->emit_present || self->first_present) {
const FLOAT clear_color[] = { 0.0f, 0.0f, 0.0f, 1.0f }; const FLOAT clear_color[] = { 0.0f, 0.0f, 0.0f, 1.0f };
context->ClearRenderTargetView (rtv, clear_color); context->ClearRenderTargetView (rtv, clear_color);
} }
@ -987,12 +987,10 @@ gst_d3d11_window_present (GstD3D11Window * self, GstBuffer * buffer,
viewport.MinDepth = 0.0f; viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f; viewport.MaxDepth = 1.0f;
g_object_set (self->converter, "dest-x", (gint) self->render_rect.left, g_object_set (self->converter, "dest-x", (gint) viewport.TopLeftX,
"dest-y", (gint) self->render_rect.top, "dest-y", (gint) viewport.TopLeftY,
"dest-width", "dest-width", (gint) viewport.Width,
(gint) (self->render_rect.right - self->render_rect.left), "dest-height", (gint) viewport.Height, nullptr);
"dest-height",
(gint) (self->render_rect.bottom - self->render_rect.top), nullptr);
if (!gst_d3d11_need_transform (self->rotation_x, self->rotation_y, if (!gst_d3d11_need_transform (self->rotation_x, self->rotation_y,
self->rotation_z, self->scale_x, self->scale_y)) { self->rotation_z, self->scale_x, self->scale_y)) {
@ -1196,7 +1194,7 @@ gst_d3d11_window_get_native_type_to_string (GstD3D11WindowNativeType type)
} }
void void
gst_d3d11_window_set_orientation (GstD3D11Window * window, gst_d3d11_window_set_orientation (GstD3D11Window * window, gboolean immediate,
GstVideoOrientationMethod method, gfloat fov, gboolean ortho, GstVideoOrientationMethod method, gfloat fov, gboolean ortho,
gfloat rotation_x, gfloat rotation_y, gfloat rotation_z, gfloat rotation_x, gfloat rotation_y, gfloat rotation_z,
gfloat scale_x, gfloat scale_y) gfloat scale_x, gfloat scale_y)
@ -1213,10 +1211,11 @@ gst_d3d11_window_set_orientation (GstD3D11Window * window,
window->rotation_y = rotation_y; window->rotation_y = rotation_y;
window->rotation_z = rotation_z; window->rotation_z = rotation_z;
window->scale_x = scale_y; window->scale_x = scale_y;
if (window->swap_chain) { window->first_present = TRUE;
GstD3D11WindowClass *klass = GST_D3D11_WINDOW_GET_CLASS (window); if (immediate && window->swap_chain && window->backbuffer
&& window->cached_buffer) {
klass->on_resize (window, window->surface_width, window->surface_height); gst_d3d11_window_present (window, window->cached_buffer,
window->backbuffer, window->msaa_buffer);
} }
} }
} }

View file

@ -187,6 +187,7 @@ void gst_d3d11_window_set_title (GstD3D11Window * window,
const gchar *title); const gchar *title);
void gst_d3d11_window_set_orientation (GstD3D11Window * window, void gst_d3d11_window_set_orientation (GstD3D11Window * window,
gboolean immediate,
GstVideoOrientationMethod method, GstVideoOrientationMethod method,
gfloat fov, gfloat fov,
gboolean ortho, gboolean ortho,