glwindow/win32: Don't use condition variables for message synchronization

Using a single condition variable for synchronization across all GL
messages is very slow on Windows and uses up to 20% CPU usage in some
workloads due to lock contention and false broadcasts.

Using per-message event handles reduces the CPU usage to negligible
amounts despite having to allocate a new event handle for each
message.
This commit is contained in:
Nirbheek Chauhan 2019-03-11 16:59:36 +05:30 committed by Matthew Waters
parent 36ec18c230
commit 045137d340

View file

@ -61,6 +61,8 @@ static void gst_gl_window_win32_draw (GstGLWindow * window);
gboolean gst_gl_window_win32_open (GstGLWindow * window, GError ** error);
void gst_gl_window_win32_close (GstGLWindow * window);
static void release_parent_win_id (GstGLWindowWin32 * window_win32);
static void gst_gl_window_win32_send_message (GstGLWindow * window,
GstGLWindowCB callback, gpointer data);
static void
gst_gl_window_win32_class_init (GstGLWindowWin32Class * klass)
@ -77,6 +79,8 @@ gst_gl_window_win32_class_init (GstGLWindowWin32Class * klass)
window_class->show = GST_DEBUG_FUNCPTR (gst_gl_window_win32_show);
window_class->open = GST_DEBUG_FUNCPTR (gst_gl_window_win32_open);
window_class->close = GST_DEBUG_FUNCPTR (gst_gl_window_win32_close);
window_class->send_message =
GST_DEBUG_FUNCPTR (gst_gl_window_win32_send_message);
}
static void
@ -500,3 +504,37 @@ sub_class_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
return CallWindowProc (window_parent_proc, hWnd, uMsg, wParam, lParam);
}
typedef struct _GstGLWin32SyncMessage
{
GstGLWindowCB callback;
gpointer data;
HANDLE *event;
} GstGLWin32SyncMessage;
static void
_run_message_sync (GstGLWin32SyncMessage * message)
{
if (message->callback)
message->callback (message->data);
SetEvent (message->event);
}
void
gst_gl_window_win32_send_message (GstGLWindow * window,
GstGLWindowCB callback, gpointer data)
{
GstGLWin32SyncMessage message;
message.callback = callback;
message.data = data;
message.event = CreateEvent (NULL, FALSE, FALSE, NULL);
gst_gl_window_send_message_async (window, (GstGLWindowCB) _run_message_sync,
&message, NULL);
WaitForSingleObject (message.event, INFINITE);
CloseHandle (message.event);
}