display->gl_thread = NULL;
display->gl_window = NULL;
display->winId = 0;
- display->win_xpos = 0;
- display->win_ypos = 0;
display->visible = FALSE;
display->isAlive = TRUE;
display->texture_pool = g_hash_table_new (g_direct_hash, g_direct_equal);
if (display->gl_thread)
{
- g_thread_join (display->gl_thread);
+ gpointer ret = g_thread_join (display->gl_thread);
GST_INFO ("gl thread joined");
+ g_assert (ret == NULL);
display->gl_thread = NULL;
}
//------------------ 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 */
gpointer
gst_gl_display_thread_create_context (GstGLDisplay *display)
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
err = glewInit();
* Called by the first gl element of a video/x-raw-gl flow */
void
gst_gl_display_create_context (GstGLDisplay *display,
- GLint x, GLint y,
GLint width, GLint height,
- gulong winId,
- gboolean visible)
+ gulong winId)
{
gst_gl_display_lock (display);
display->winId = winId;
- display->win_xpos = x;
- display->win_ypos = y;
display->upload_width = width;
display->upload_height = height;
- display->visible = visible;
display->gl_thread = g_thread_create (
(GThreadFunc) gst_gl_display_thread_create_context, display, TRUE, NULL);
GST_GL_DISPLAY_PROJECTION_PERSPECIVE
} 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
typedef struct _GstGLDisplayTex {
GLuint texture;
GThread* gl_thread;
GstGLWindow* gl_window;
gulong winId;
- gint win_xpos;
- gint win_ypos;
gboolean visible;
gboolean isAlive;
GHashTable* texture_pool;
GstGLDisplay* gst_gl_display_new (void);
void gst_gl_display_create_context (GstGLDisplay* display,
- GLint x, GLint y,
GLint width, GLint height,
- gulong winId,
- gboolean visible);
+ gulong winId);
void gst_gl_display_set_visible_context (GstGLDisplay* display, gboolean visible);
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);
obj_class->finalize = gst_gl_window_finalize;
- GetClassInfo ((HINSTANCE)klass->instance, "GSTGL", &wc);
+ atom = GetClassInfo ((HINSTANCE)klass->instance, "GSTGL", &wc);
ZeroMemory (&wc, sizeof(WNDCLASS));
wc.hIcon = LoadIcon( NULL, IDI_WINLOGO );
wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
- wc.hbrBackground = NULL;
+ wc.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = "GSTGL";
atom = RegisterClass (&wc);
-
- g_assert (atom);
-
- g_debug ("GSTGL window class registered\n");
}
static void
GstGLWindowPrivate *priv = window->priv;
GstGLWindowClass* klass = GST_GL_WINDOW_GET_CLASS (window);
- static gint x = 50;
+ static gint x = 0;
static gint y = 0;
- y = 50 + height * y++;
+ x += 20;
+ y += 20;
priv->internal_win_id = 0;
priv->external_win_id = 0;
UpdateWindow (priv->internal_win_id);
ShowCursor (TRUE);
- wglMakeCurrent (priv->device, priv->gl_context);
-
- return window;
+ if (wglMakeCurrent (priv->device, priv->gl_context))
+ return window;
+ else
+ {
+ g_debug ("Failed to make opengl context current");
+ return NULL;
+ }
}
GQuark
BeginPaint (priv->external_win_id, &ps);
priv->draw_cb (priv->draw_data); //FIXME: wrong thread caller
- //glFlush();
+ glFlush();
SwapBuffers (priv->device);
EndPaint (priv->external_win_id, &ps);
}
GstGLWindowPrivate *priv = window->priv;
LRESULT res = PostMessage(priv->internal_win_id, WM_CLOSE, 0, 0);
g_assert (SUCCEEDED (res));
+ g_debug ("end loop requested\n");
}
}
LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
- static gboolean created = FALSE;
-
if (uMsg == WM_CREATE) {
GstGLWindow *window = (GstGLWindow *) (((LPCREATESTRUCT) lParam)->lpCreateParams);
priv->device = GetDC (hWnd);
gst_gl_window_set_pixel_format (window);
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);
}
- created = TRUE;
-
return 0;
}
- else if (created) {
+ else if (GetWindowLongPtr(hWnd, GWLP_USERDATA)) {
GstGLWindow *window = (GstGLWindow *) (guint64) GetWindowLongPtr(hWnd, GWLP_USERDATA);
GstGLWindowPrivate *priv = NULL;
g_assert (priv);
+ g_assert (priv->internal_win_id == hWnd);
+
switch ( uMsg ) {
case WM_SIZE:
g_debug ("WM_CLOSE\n");
if (priv->close_cb)
priv->close_cb (priv->close_data);
- DestroyWindow(hWnd);
- break;
- }
+ wglMakeCurrent (NULL, NULL);
- case WM_DESTROY:
- {
- g_debug ("WM_DESTROY\n");
- created = FALSE;
+ if (priv->gl_context)
+ wglDeleteContext (priv->gl_context);
+
+ if (priv->internal_win_id)
+ DestroyWindow(priv->internal_win_id);
+
+ SetWindowLongPtr (hWnd, GWLP_USERDATA, 0);
+ DestroyWindow(hWnd);
PostQuitMessage (0);
break;
}
break;
}
+ case WM_ERASEBKGND:
+ return TRUE;
+
default:
return DefWindowProc( hWnd, uMsg, wParam, lParam );
}