[251/906] Properly clean OpenGL contexts
This commit is contained in:
parent
a6fdb20154
commit
fc9479d289
@ -108,8 +108,6 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass)
|
|||||||
display->gl_thread = NULL;
|
display->gl_thread = NULL;
|
||||||
display->gl_window = NULL;
|
display->gl_window = NULL;
|
||||||
display->winId = 0;
|
display->winId = 0;
|
||||||
display->win_xpos = 0;
|
|
||||||
display->win_ypos = 0;
|
|
||||||
display->visible = FALSE;
|
display->visible = FALSE;
|
||||||
display->isAlive = TRUE;
|
display->isAlive = TRUE;
|
||||||
display->texture_pool = g_hash_table_new (g_direct_hash, g_direct_equal);
|
display->texture_pool = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||||
@ -355,8 +353,9 @@ gst_gl_display_finalize (GObject* object)
|
|||||||
|
|
||||||
if (display->gl_thread)
|
if (display->gl_thread)
|
||||||
{
|
{
|
||||||
g_thread_join (display->gl_thread);
|
gpointer ret = g_thread_join (display->gl_thread);
|
||||||
GST_INFO ("gl thread joined");
|
GST_INFO ("gl thread joined");
|
||||||
|
g_assert (ret == NULL);
|
||||||
display->gl_thread = NULL;
|
display->gl_thread = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -389,10 +388,6 @@ gst_gl_display_finalize (GObject* object)
|
|||||||
//------------------ BEGIN GL THREAD ACTIONS -----------------
|
//------------------ BEGIN GL THREAD ACTIONS -----------------
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
|
|
||||||
//The following functions are thread safe because
|
|
||||||
//called by the "gst_gl_display_thread_dispatch_action"
|
|
||||||
//in a lock/unlock scope.
|
|
||||||
|
|
||||||
/* Called in the gl thread */
|
/* Called in the gl thread */
|
||||||
gpointer
|
gpointer
|
||||||
gst_gl_display_thread_create_context (GstGLDisplay *display)
|
gst_gl_display_thread_create_context (GstGLDisplay *display)
|
||||||
@ -401,9 +396,15 @@ gst_gl_display_thread_create_context (GstGLDisplay *display)
|
|||||||
|
|
||||||
display->gl_window = gst_gl_window_new (display->upload_width, display->upload_height);
|
display->gl_window = gst_gl_window_new (display->upload_width, display->upload_height);
|
||||||
|
|
||||||
GST_INFO ("gl window created");
|
if (!display->gl_window)
|
||||||
|
{
|
||||||
|
display->isAlive = FALSE;
|
||||||
|
GST_ERROR_OBJECT (display, "Failed to create gl window");
|
||||||
|
g_cond_signal (display->cond_create_context);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
gst_gl_window_visible (display->gl_window, display->visible);
|
GST_INFO ("gl window created");
|
||||||
|
|
||||||
//Init glew
|
//Init glew
|
||||||
err = glewInit();
|
err = glewInit();
|
||||||
@ -1580,19 +1581,14 @@ gst_gl_display_new (void)
|
|||||||
* Called by the first gl element of a video/x-raw-gl flow */
|
* Called by the first gl element of a video/x-raw-gl flow */
|
||||||
void
|
void
|
||||||
gst_gl_display_create_context (GstGLDisplay *display,
|
gst_gl_display_create_context (GstGLDisplay *display,
|
||||||
GLint x, GLint y,
|
|
||||||
GLint width, GLint height,
|
GLint width, GLint height,
|
||||||
gulong winId,
|
gulong winId)
|
||||||
gboolean visible)
|
|
||||||
{
|
{
|
||||||
gst_gl_display_lock (display);
|
gst_gl_display_lock (display);
|
||||||
|
|
||||||
display->winId = winId;
|
display->winId = winId;
|
||||||
display->win_xpos = x;
|
|
||||||
display->win_ypos = y;
|
|
||||||
display->upload_width = width;
|
display->upload_width = width;
|
||||||
display->upload_height = height;
|
display->upload_height = height;
|
||||||
display->visible = visible;
|
|
||||||
|
|
||||||
display->gl_thread = g_thread_create (
|
display->gl_thread = g_thread_create (
|
||||||
(GThreadFunc) gst_gl_display_thread_create_context, display, TRUE, NULL);
|
(GThreadFunc) gst_gl_display_thread_create_context, display, TRUE, NULL);
|
||||||
|
@ -56,39 +56,6 @@ typedef enum {
|
|||||||
GST_GL_DISPLAY_PROJECTION_PERSPECIVE
|
GST_GL_DISPLAY_PROJECTION_PERSPECIVE
|
||||||
} GstGLDisplayProjection;
|
} GstGLDisplayProjection;
|
||||||
|
|
||||||
|
|
||||||
//Message type
|
|
||||||
typedef enum {
|
|
||||||
GST_GL_DISPLAY_ACTION_CREATE_CONTEXT,
|
|
||||||
GST_GL_DISPLAY_ACTION_DESTROY_CONTEXT,
|
|
||||||
GST_GL_DISPLAY_ACTION_CHANGE_CONTEXT,
|
|
||||||
GST_GL_DISPLAY_ACTION_VISIBLE_CONTEXT,
|
|
||||||
GST_GL_DISPLAY_ACTION_RESIZE_CONTEXT,
|
|
||||||
GST_GL_DISPLAY_ACTION_REDISPLAY_CONTEXT,
|
|
||||||
GST_GL_DISPLAY_ACTION_GENERIC,
|
|
||||||
GST_GL_DISPLAY_ACTION_GEN_TEXTURE,
|
|
||||||
GST_GL_DISPLAY_ACTION_DEL_TEXTURE,
|
|
||||||
GST_GL_DISPLAY_ACTION_INIT_UPLOAD,
|
|
||||||
GST_GL_DISPLAY_ACTION_DO_UPLOAD,
|
|
||||||
GST_GL_DISPLAY_ACTION_INIT_DOWNLOAD,
|
|
||||||
GST_GL_DISPLAY_ACTION_DO_DOWNLOAD,
|
|
||||||
GST_GL_DISPLAY_ACTION_GEN_FBO,
|
|
||||||
GST_GL_DISPLAY_ACTION_USE_FBO,
|
|
||||||
GST_GL_DISPLAY_ACTION_DEL_FBO,
|
|
||||||
GST_GL_DISPLAY_ACTION_GEN_SHADER,
|
|
||||||
GST_GL_DISPLAY_ACTION_DEL_SHADER
|
|
||||||
|
|
||||||
} GstGLDisplayAction;
|
|
||||||
|
|
||||||
|
|
||||||
//Message to communicate with the gl thread
|
|
||||||
typedef struct _GstGLDisplayMsg {
|
|
||||||
GstGLDisplayAction action;
|
|
||||||
gint glutWinId;
|
|
||||||
GstGLDisplay* display;
|
|
||||||
} GstGLDisplayMsg;
|
|
||||||
|
|
||||||
|
|
||||||
//Texture pool elements
|
//Texture pool elements
|
||||||
typedef struct _GstGLDisplayTex {
|
typedef struct _GstGLDisplayTex {
|
||||||
GLuint texture;
|
GLuint texture;
|
||||||
@ -114,8 +81,6 @@ struct _GstGLDisplay {
|
|||||||
GThread* gl_thread;
|
GThread* gl_thread;
|
||||||
GstGLWindow* gl_window;
|
GstGLWindow* gl_window;
|
||||||
gulong winId;
|
gulong winId;
|
||||||
gint win_xpos;
|
|
||||||
gint win_ypos;
|
|
||||||
gboolean visible;
|
gboolean visible;
|
||||||
gboolean isAlive;
|
gboolean isAlive;
|
||||||
GHashTable* texture_pool;
|
GHashTable* texture_pool;
|
||||||
@ -248,10 +213,8 @@ GType gst_gl_display_get_type (void);
|
|||||||
GstGLDisplay* gst_gl_display_new (void);
|
GstGLDisplay* gst_gl_display_new (void);
|
||||||
|
|
||||||
void gst_gl_display_create_context (GstGLDisplay* display,
|
void gst_gl_display_create_context (GstGLDisplay* display,
|
||||||
GLint x, GLint y,
|
|
||||||
GLint width, GLint height,
|
GLint width, GLint height,
|
||||||
gulong winId,
|
gulong winId);
|
||||||
gboolean visible);
|
|
||||||
void gst_gl_display_set_visible_context (GstGLDisplay* display, gboolean visible);
|
void gst_gl_display_set_visible_context (GstGLDisplay* display, gboolean visible);
|
||||||
void gst_gl_display_resize_context (GstGLDisplay* display, gint width, gint height);
|
void gst_gl_display_resize_context (GstGLDisplay* display, gint width, gint height);
|
||||||
gboolean gst_gl_display_redisplay (GstGLDisplay* display, GLuint texture, gint width, gint height);
|
gboolean gst_gl_display_redisplay (GstGLDisplay* display, GLuint texture, gint width, gint height);
|
||||||
|
@ -96,7 +96,7 @@ gst_gl_window_class_init (GstGLWindowClass * klass)
|
|||||||
|
|
||||||
obj_class->finalize = gst_gl_window_finalize;
|
obj_class->finalize = gst_gl_window_finalize;
|
||||||
|
|
||||||
GetClassInfo ((HINSTANCE)klass->instance, "GSTGL", &wc);
|
atom = GetClassInfo ((HINSTANCE)klass->instance, "GSTGL", &wc);
|
||||||
|
|
||||||
ZeroMemory (&wc, sizeof(WNDCLASS));
|
ZeroMemory (&wc, sizeof(WNDCLASS));
|
||||||
|
|
||||||
@ -107,15 +107,11 @@ gst_gl_window_class_init (GstGLWindowClass * klass)
|
|||||||
wc.hIcon = LoadIcon( NULL, IDI_WINLOGO );
|
wc.hIcon = LoadIcon( NULL, IDI_WINLOGO );
|
||||||
wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
|
wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
|
||||||
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
|
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
|
||||||
wc.hbrBackground = NULL;
|
wc.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH);
|
||||||
wc.lpszMenuName = NULL;
|
wc.lpszMenuName = NULL;
|
||||||
wc.lpszClassName = "GSTGL";
|
wc.lpszClassName = "GSTGL";
|
||||||
|
|
||||||
atom = RegisterClass (&wc);
|
atom = RegisterClass (&wc);
|
||||||
|
|
||||||
g_assert (atom);
|
|
||||||
|
|
||||||
g_debug ("GSTGL window class registered\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -138,9 +134,10 @@ gst_gl_window_new (gint width, gint height)
|
|||||||
GstGLWindowPrivate *priv = window->priv;
|
GstGLWindowPrivate *priv = window->priv;
|
||||||
GstGLWindowClass* klass = GST_GL_WINDOW_GET_CLASS (window);
|
GstGLWindowClass* klass = GST_GL_WINDOW_GET_CLASS (window);
|
||||||
|
|
||||||
static gint x = 50;
|
static gint x = 0;
|
||||||
static gint y = 0;
|
static gint y = 0;
|
||||||
y = 50 + height * y++;
|
x += 20;
|
||||||
|
y += 20;
|
||||||
|
|
||||||
priv->internal_win_id = 0;
|
priv->internal_win_id = 0;
|
||||||
priv->external_win_id = 0;
|
priv->external_win_id = 0;
|
||||||
@ -180,9 +177,13 @@ gst_gl_window_new (gint width, gint height)
|
|||||||
UpdateWindow (priv->internal_win_id);
|
UpdateWindow (priv->internal_win_id);
|
||||||
ShowCursor (TRUE);
|
ShowCursor (TRUE);
|
||||||
|
|
||||||
wglMakeCurrent (priv->device, priv->gl_context);
|
if (wglMakeCurrent (priv->device, priv->gl_context))
|
||||||
|
return window;
|
||||||
return window;
|
else
|
||||||
|
{
|
||||||
|
g_debug ("Failed to make opengl context current");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GQuark
|
GQuark
|
||||||
@ -324,7 +325,7 @@ gst_gl_window_draw (GstGLWindow *window)
|
|||||||
|
|
||||||
BeginPaint (priv->external_win_id, &ps);
|
BeginPaint (priv->external_win_id, &ps);
|
||||||
priv->draw_cb (priv->draw_data); //FIXME: wrong thread caller
|
priv->draw_cb (priv->draw_data); //FIXME: wrong thread caller
|
||||||
//glFlush();
|
glFlush();
|
||||||
SwapBuffers (priv->device);
|
SwapBuffers (priv->device);
|
||||||
EndPaint (priv->external_win_id, &ps);
|
EndPaint (priv->external_win_id, &ps);
|
||||||
}
|
}
|
||||||
@ -386,6 +387,7 @@ gst_gl_window_quit_loop (GstGLWindow *window)
|
|||||||
GstGLWindowPrivate *priv = window->priv;
|
GstGLWindowPrivate *priv = window->priv;
|
||||||
LRESULT res = PostMessage(priv->internal_win_id, WM_CLOSE, 0, 0);
|
LRESULT res = PostMessage(priv->internal_win_id, WM_CLOSE, 0, 0);
|
||||||
g_assert (SUCCEEDED (res));
|
g_assert (SUCCEEDED (res));
|
||||||
|
g_debug ("end loop requested\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -451,8 +453,6 @@ gst_gl_window_set_pixel_format (GstGLWindow *window)
|
|||||||
|
|
||||||
LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
static gboolean created = FALSE;
|
|
||||||
|
|
||||||
if (uMsg == WM_CREATE) {
|
if (uMsg == WM_CREATE) {
|
||||||
|
|
||||||
GstGLWindow *window = (GstGLWindow *) (((LPCREATESTRUCT) lParam)->lpCreateParams);
|
GstGLWindow *window = (GstGLWindow *) (((LPCREATESTRUCT) lParam)->lpCreateParams);
|
||||||
@ -468,14 +468,17 @@ LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
|
|||||||
priv->device = GetDC (hWnd);
|
priv->device = GetDC (hWnd);
|
||||||
gst_gl_window_set_pixel_format (window);
|
gst_gl_window_set_pixel_format (window);
|
||||||
priv->gl_context = wglCreateContext (priv->device);
|
priv->gl_context = wglCreateContext (priv->device);
|
||||||
|
if (priv->gl_context)
|
||||||
|
g_debug ("gl context created: %d\n", priv->gl_context);
|
||||||
|
else
|
||||||
|
g_debug ("failed to create glcontext %d\n", hWnd);
|
||||||
|
g_assert (priv->gl_context);
|
||||||
ReleaseDC (hWnd, priv->device);
|
ReleaseDC (hWnd, priv->device);
|
||||||
}
|
}
|
||||||
|
|
||||||
created = TRUE;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (created) {
|
else if (GetWindowLongPtr(hWnd, GWLP_USERDATA)) {
|
||||||
|
|
||||||
GstGLWindow *window = (GstGLWindow *) (guint64) GetWindowLongPtr(hWnd, GWLP_USERDATA);
|
GstGLWindow *window = (GstGLWindow *) (guint64) GetWindowLongPtr(hWnd, GWLP_USERDATA);
|
||||||
GstGLWindowPrivate *priv = NULL;
|
GstGLWindowPrivate *priv = NULL;
|
||||||
@ -486,6 +489,8 @@ LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
|
|||||||
|
|
||||||
g_assert (priv);
|
g_assert (priv);
|
||||||
|
|
||||||
|
g_assert (priv->internal_win_id == hWnd);
|
||||||
|
|
||||||
switch ( uMsg ) {
|
switch ( uMsg ) {
|
||||||
|
|
||||||
case WM_SIZE:
|
case WM_SIZE:
|
||||||
@ -513,14 +518,16 @@ LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
|
|||||||
g_debug ("WM_CLOSE\n");
|
g_debug ("WM_CLOSE\n");
|
||||||
if (priv->close_cb)
|
if (priv->close_cb)
|
||||||
priv->close_cb (priv->close_data);
|
priv->close_cb (priv->close_data);
|
||||||
DestroyWindow(hWnd);
|
wglMakeCurrent (NULL, NULL);
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case WM_DESTROY:
|
if (priv->gl_context)
|
||||||
{
|
wglDeleteContext (priv->gl_context);
|
||||||
g_debug ("WM_DESTROY\n");
|
|
||||||
created = FALSE;
|
if (priv->internal_win_id)
|
||||||
|
DestroyWindow(priv->internal_win_id);
|
||||||
|
|
||||||
|
SetWindowLongPtr (hWnd, GWLP_USERDATA, 0);
|
||||||
|
DestroyWindow(hWnd);
|
||||||
PostQuitMessage (0);
|
PostQuitMessage (0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -540,6 +547,9 @@ LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case WM_ERASEBKGND:
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return DefWindowProc( hWnd, uMsg, wParam, lParam );
|
return DefWindowProc( hWnd, uMsg, wParam, lParam );
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user