mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-07 07:58:51 +00:00
[701/906] display: move context creation into window
This commit is contained in:
parent
9c633e658a
commit
c6988cb064
12 changed files with 583 additions and 420 deletions
|
@ -62,9 +62,7 @@ void gst_gl_display_thread_run_generic (GstGLDisplay * display);
|
||||||
|
|
||||||
struct _GstGLDisplayPrivate
|
struct _GstGLDisplayPrivate
|
||||||
{
|
{
|
||||||
/* conditions */
|
GstGLWindow *window;
|
||||||
GCond cond_create_context;
|
|
||||||
GCond cond_destroy_context;
|
|
||||||
|
|
||||||
/* generic gl code */
|
/* generic gl code */
|
||||||
GstGLDisplayThreadFunc generic_callback;
|
GstGLDisplayThreadFunc generic_callback;
|
||||||
|
@ -91,13 +89,8 @@ gst_gl_display_init (GstGLDisplay * display)
|
||||||
/* thread safe */
|
/* thread safe */
|
||||||
g_mutex_init (&display->mutex);
|
g_mutex_init (&display->mutex);
|
||||||
|
|
||||||
g_cond_init (&display->priv->cond_create_context);
|
|
||||||
g_cond_init (&display->priv->cond_destroy_context);
|
|
||||||
|
|
||||||
display->gl_vtable = g_slice_alloc0 (sizeof (GstGLFuncs));
|
display->gl_vtable = g_slice_alloc0 (sizeof (GstGLFuncs));
|
||||||
|
|
||||||
display->gl_window = gst_gl_window_new ();
|
|
||||||
|
|
||||||
gst_gl_memory_init ();
|
gst_gl_memory_init ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,39 +99,8 @@ gst_gl_display_finalize (GObject * object)
|
||||||
{
|
{
|
||||||
GstGLDisplay *display = GST_GL_DISPLAY (object);
|
GstGLDisplay *display = GST_GL_DISPLAY (object);
|
||||||
|
|
||||||
if (display->gl_window) {
|
|
||||||
gst_gl_display_lock (display);
|
|
||||||
|
|
||||||
gst_gl_window_set_resize_callback (display->gl_window, NULL, NULL);
|
|
||||||
gst_gl_window_set_draw_callback (display->gl_window, NULL, NULL);
|
|
||||||
gst_gl_window_set_close_callback (display->gl_window, NULL, NULL);
|
|
||||||
|
|
||||||
if (display->context_created) {
|
|
||||||
GST_INFO ("send quit gl window loop");
|
|
||||||
gst_gl_window_quit (display->gl_window,
|
|
||||||
GST_GL_WINDOW_CB (gst_gl_display_thread_destroy_context), display);
|
|
||||||
|
|
||||||
GST_INFO ("quit sent to gl window loop");
|
|
||||||
|
|
||||||
g_cond_wait (&display->priv->cond_destroy_context, &display->mutex);
|
|
||||||
GST_INFO ("quit received from gl window");
|
|
||||||
}
|
|
||||||
gst_gl_display_unlock (display);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (display->gl_thread) {
|
|
||||||
gpointer ret = g_thread_join (display->gl_thread);
|
|
||||||
GST_INFO ("gl thread joined");
|
|
||||||
if (ret != NULL)
|
|
||||||
GST_ERROR ("gl thread returned a not null pointer");
|
|
||||||
display->gl_thread = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_mutex_clear (&display->mutex);
|
g_mutex_clear (&display->mutex);
|
||||||
|
|
||||||
g_cond_clear (&display->priv->cond_destroy_context);
|
|
||||||
g_cond_clear (&display->priv->cond_create_context);
|
|
||||||
|
|
||||||
if (display->error_message) {
|
if (display->error_message) {
|
||||||
g_free (display->error_message);
|
g_free (display->error_message);
|
||||||
display->error_message = NULL;
|
display->error_message = NULL;
|
||||||
|
@ -148,271 +110,13 @@ gst_gl_display_finalize (GObject * object)
|
||||||
g_slice_free (GstGLFuncs, display->gl_vtable);
|
g_slice_free (GstGLFuncs, display->gl_vtable);
|
||||||
display->gl_vtable = NULL;
|
display->gl_vtable = NULL;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
if (display->priv->window) {
|
||||||
_create_context_gles2 (GstGLDisplay * display, gint * gl_major, gint * gl_minor)
|
gst_object_unref (display->priv->window);
|
||||||
{
|
display->priv->window = NULL;
|
||||||
const GstGLFuncs *gl;
|
|
||||||
GLenum gl_err = GL_NO_ERROR;
|
|
||||||
|
|
||||||
gl = display->gl_vtable;
|
|
||||||
|
|
||||||
GST_INFO ("GL_VERSION: %s", gl->GetString (GL_VERSION));
|
|
||||||
GST_INFO ("GL_SHADING_LANGUAGE_VERSION: %s",
|
|
||||||
gl->GetString (GL_SHADING_LANGUAGE_VERSION));
|
|
||||||
GST_INFO ("GL_VENDOR: %s", gl->GetString (GL_VENDOR));
|
|
||||||
GST_INFO ("GL_RENDERER: %s", gl->GetString (GL_RENDERER));
|
|
||||||
|
|
||||||
gl_err = gl->GetError ();
|
|
||||||
if (gl_err != GL_NO_ERROR) {
|
|
||||||
gst_gl_display_set_error (display, "glGetString error: 0x%x", gl_err);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
#if GST_GL_HAVE_GLES2
|
|
||||||
if (!GL_ES_VERSION_2_0) {
|
|
||||||
gst_gl_display_set_error (display, "OpenGL|ES >= 2.0 is required");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
_gst_gl_feature_check_ext_functions (display, 0, 0,
|
|
||||||
(const gchar *) gl->GetString (GL_EXTENSIONS));
|
|
||||||
|
|
||||||
if (gl_major)
|
|
||||||
*gl_major = 2;
|
|
||||||
if (gl_minor)
|
|
||||||
*gl_minor = 0;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
_create_context_opengl (GstGLDisplay * display, gint * gl_major,
|
|
||||||
gint * gl_minor)
|
|
||||||
{
|
|
||||||
const GstGLFuncs *gl;
|
|
||||||
guint maj, min;
|
|
||||||
GLenum gl_err = GL_NO_ERROR;
|
|
||||||
GString *opengl_version = NULL;
|
|
||||||
|
|
||||||
gl = display->gl_vtable;
|
|
||||||
|
|
||||||
GST_INFO ("GL_VERSION: %s", gl->GetString (GL_VERSION));
|
|
||||||
GST_INFO ("GL_SHADING_LANGUAGE_VERSION: %s",
|
|
||||||
gl->GetString (GL_SHADING_LANGUAGE_VERSION));
|
|
||||||
GST_INFO ("GL_VENDOR: %s", gl->GetString (GL_VENDOR));
|
|
||||||
GST_INFO ("GL_RENDERER: %s", gl->GetString (GL_RENDERER));
|
|
||||||
|
|
||||||
gl_err = gl->GetError ();
|
|
||||||
if (gl_err != GL_NO_ERROR) {
|
|
||||||
gst_gl_display_set_error (display, "glGetString error: 0x%x", gl_err);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
opengl_version =
|
|
||||||
g_string_truncate (g_string_new ((gchar *) gl->GetString (GL_VERSION)),
|
|
||||||
3);
|
|
||||||
|
|
||||||
sscanf (opengl_version->str, "%d.%d", &maj, &min);
|
|
||||||
|
|
||||||
g_string_free (opengl_version, TRUE);
|
|
||||||
|
|
||||||
/* OpenGL > 1.2.0 */
|
|
||||||
if ((maj < 1) || (maj < 2 && maj >= 1 && min < 2)) {
|
|
||||||
gst_gl_display_set_error (display, "OpenGL >= 1.2.0 required, found %u.%u",
|
|
||||||
maj, min);
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_gst_gl_feature_check_ext_functions (display, maj, min,
|
G_OBJECT_CLASS (gst_gl_display_parent_class)->finalize (object);
|
||||||
(const gchar *) gl->GetString (GL_EXTENSIONS));
|
|
||||||
|
|
||||||
if (gl_major)
|
|
||||||
*gl_major = maj;
|
|
||||||
if (gl_minor)
|
|
||||||
*gl_minor = min;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
GstGLAPI
|
|
||||||
_compiled_api (void)
|
|
||||||
{
|
|
||||||
GstGLAPI ret = GST_GL_API_NONE;
|
|
||||||
|
|
||||||
#if GST_GL_HAVE_OPENGL
|
|
||||||
ret |= GST_GL_API_OPENGL;
|
|
||||||
#endif
|
|
||||||
#if GST_GL_HAVE_GLES2
|
|
||||||
ret |= GST_GL_API_GLES2;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
GstGLAPI
|
|
||||||
_parse_gl_api (const gchar * apis_s)
|
|
||||||
{
|
|
||||||
GstGLAPI ret = GST_GL_API_NONE;
|
|
||||||
gchar *apis = (gchar *) apis_s;
|
|
||||||
|
|
||||||
while (apis) {
|
|
||||||
if (apis[0] == '\0') {
|
|
||||||
break;
|
|
||||||
} else if (apis[0] == ' ' || apis[0] == ',') {
|
|
||||||
apis = &apis[1];
|
|
||||||
} else if (g_strstr_len (apis, 7, "opengl3")) {
|
|
||||||
ret |= GST_GL_API_OPENGL3;
|
|
||||||
apis = &apis[7];
|
|
||||||
} else if (g_strstr_len (apis, 6, "opengl")) {
|
|
||||||
ret |= GST_GL_API_OPENGL;
|
|
||||||
apis = &apis[6];
|
|
||||||
} else if (g_strstr_len (apis, 5, "gles1")) {
|
|
||||||
ret |= GST_GL_API_GLES;
|
|
||||||
apis = &apis[5];
|
|
||||||
} else if (g_strstr_len (apis, 5, "gles2")) {
|
|
||||||
ret |= GST_GL_API_GLES2;
|
|
||||||
apis = &apis[5];
|
|
||||||
} else if (g_strstr_len (apis, 5, "gles3")) {
|
|
||||||
ret |= GST_GL_API_GLES3;
|
|
||||||
apis = &apis[5];
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret == GST_GL_API_NONE)
|
|
||||||
ret = GST_GL_API_ANY;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
gpointer
|
|
||||||
gst_gl_display_thread_create_context (GstGLDisplay * display)
|
|
||||||
{
|
|
||||||
GstGLFuncs *gl;
|
|
||||||
gint gl_major = 0;
|
|
||||||
gboolean ret = FALSE;
|
|
||||||
GError *error = NULL;
|
|
||||||
GstGLAPI compiled_api, user_api;
|
|
||||||
gchar *api_string;
|
|
||||||
gchar *compiled_api_s;
|
|
||||||
gchar *user_api_string;
|
|
||||||
const gchar *user_choice;
|
|
||||||
|
|
||||||
gst_gl_display_lock (display);
|
|
||||||
|
|
||||||
gl = display->gl_vtable;
|
|
||||||
compiled_api = _compiled_api ();
|
|
||||||
|
|
||||||
if (!display->gl_window) {
|
|
||||||
gst_gl_display_set_error (display, "Failed to create opengl window");
|
|
||||||
goto failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
user_choice = g_getenv ("GST_GL_API");
|
|
||||||
|
|
||||||
user_api = _parse_gl_api (user_choice);
|
|
||||||
user_api_string = gst_gl_api_string (user_api);
|
|
||||||
|
|
||||||
compiled_api_s = gst_gl_api_string (compiled_api);
|
|
||||||
|
|
||||||
GST_INFO ("Attempting to create opengl context. user chosen api(s):%s, "
|
|
||||||
"compiled api support:%s", user_api_string, compiled_api_s);
|
|
||||||
|
|
||||||
if (!gst_gl_window_create_context (display->gl_window,
|
|
||||||
compiled_api & user_api, display->external_gl_context, &error)) {
|
|
||||||
gst_gl_display_set_error (display,
|
|
||||||
error ? error->message : "Failed to create gl window");
|
|
||||||
g_free (compiled_api_s);
|
|
||||||
g_free (user_api_string);
|
|
||||||
goto failure;
|
|
||||||
}
|
|
||||||
GST_INFO ("window created context");
|
|
||||||
|
|
||||||
display->gl_api = gst_gl_window_get_gl_api (display->gl_window);
|
|
||||||
g_assert (display->gl_api != GST_GL_API_NONE
|
|
||||||
&& display->gl_api != GST_GL_API_ANY);
|
|
||||||
|
|
||||||
api_string = gst_gl_api_string (display->gl_api);
|
|
||||||
GST_INFO ("available GL APIs: %s", api_string);
|
|
||||||
|
|
||||||
if (((compiled_api & display->gl_api) & user_api) == GST_GL_API_NONE) {
|
|
||||||
gst_gl_display_set_error (display, "failed to create context, window "
|
|
||||||
"could not provide correct api. user:%s, compiled:%s, window:%s",
|
|
||||||
user_api_string, compiled_api_s, api_string);
|
|
||||||
g_free (api_string);
|
|
||||||
g_free (compiled_api_s);
|
|
||||||
g_free (user_api_string);
|
|
||||||
goto failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free (api_string);
|
|
||||||
g_free (compiled_api_s);
|
|
||||||
g_free (user_api_string);
|
|
||||||
|
|
||||||
gl->GetError =
|
|
||||||
gst_gl_window_get_proc_address (display->gl_window, "glGetError");
|
|
||||||
gl->GetString =
|
|
||||||
gst_gl_window_get_proc_address (display->gl_window, "glGetString");
|
|
||||||
|
|
||||||
if (!gl->GetError || !gl->GetString) {
|
|
||||||
gst_gl_display_set_error (display,
|
|
||||||
"could not GetProcAddress core opengl functions");
|
|
||||||
goto failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* gl api specific code */
|
|
||||||
if (!ret && USING_OPENGL (display))
|
|
||||||
ret = _create_context_opengl (display, &gl_major, NULL);
|
|
||||||
if (!ret && USING_GLES2 (display))
|
|
||||||
ret = _create_context_gles2 (display, &gl_major, NULL);
|
|
||||||
|
|
||||||
if (!ret || !gl_major) {
|
|
||||||
GST_WARNING ("GL api specific initialization failed");
|
|
||||||
goto failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_cond_signal (&display->priv->cond_create_context);
|
|
||||||
|
|
||||||
display->isAlive = TRUE;
|
|
||||||
gst_gl_display_unlock (display);
|
|
||||||
|
|
||||||
gst_gl_window_run (display->gl_window);
|
|
||||||
|
|
||||||
GST_INFO ("loop exited\n");
|
|
||||||
|
|
||||||
gst_gl_display_lock (display);
|
|
||||||
|
|
||||||
display->isAlive = FALSE;
|
|
||||||
|
|
||||||
g_object_unref (G_OBJECT (display->gl_window));
|
|
||||||
|
|
||||||
display->gl_window = NULL;
|
|
||||||
|
|
||||||
g_cond_signal (&display->priv->cond_destroy_context);
|
|
||||||
|
|
||||||
gst_gl_display_unlock (display);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
failure:
|
|
||||||
{
|
|
||||||
if (display->gl_window) {
|
|
||||||
g_object_unref (display->gl_window);
|
|
||||||
display->gl_window = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_cond_signal (&display->priv->cond_create_context);
|
|
||||||
gst_gl_display_unlock (display);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
gst_gl_display_thread_destroy_context (GstGLDisplay * display)
|
|
||||||
{
|
|
||||||
GST_INFO ("Context destroyed");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
|
@ -434,8 +138,6 @@ gst_gl_display_set_error (GstGLDisplay * display, const char *format, ...)
|
||||||
va_end (args);
|
va_end (args);
|
||||||
|
|
||||||
GST_WARNING ("%s", display->error_message);
|
GST_WARNING ("%s", display->error_message);
|
||||||
|
|
||||||
display->isAlive = FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -470,83 +172,55 @@ gst_gl_display_new (void)
|
||||||
return g_object_new (GST_GL_TYPE_DISPLAY, NULL);
|
return g_object_new (GST_GL_TYPE_DISPLAY, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create an opengl context (one context for one GstGLDisplay) */
|
|
||||||
gboolean
|
|
||||||
gst_gl_display_create_context (GstGLDisplay * display,
|
|
||||||
gulong external_gl_context)
|
|
||||||
{
|
|
||||||
gboolean isAlive = FALSE;
|
|
||||||
|
|
||||||
gst_gl_display_lock (display);
|
|
||||||
|
|
||||||
if (!display->context_created) {
|
|
||||||
display->external_gl_context = external_gl_context;
|
|
||||||
|
|
||||||
display->gl_thread = g_thread_new ("gstglcontext",
|
|
||||||
(GThreadFunc) gst_gl_display_thread_create_context, display);
|
|
||||||
|
|
||||||
g_cond_wait (&display->priv->cond_create_context, &display->mutex);
|
|
||||||
|
|
||||||
display->context_created = TRUE;
|
|
||||||
|
|
||||||
GST_INFO ("gl thread created");
|
|
||||||
}
|
|
||||||
|
|
||||||
isAlive = display->isAlive;
|
|
||||||
|
|
||||||
gst_gl_display_unlock (display);
|
|
||||||
|
|
||||||
return isAlive;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
gst_gl_display_thread_add (GstGLDisplay * display,
|
gst_gl_display_thread_add (GstGLDisplay * display,
|
||||||
GstGLDisplayThreadFunc func, gpointer data)
|
GstGLDisplayThreadFunc func, gpointer data)
|
||||||
{
|
{
|
||||||
|
g_return_if_fail (GST_IS_GL_DISPLAY (display));
|
||||||
|
g_return_if_fail (GST_GL_IS_WINDOW (display->priv->window));
|
||||||
|
g_return_if_fail (func != NULL);
|
||||||
|
|
||||||
gst_gl_display_lock (display);
|
gst_gl_display_lock (display);
|
||||||
|
|
||||||
display->priv->data = data;
|
display->priv->data = data;
|
||||||
display->priv->generic_callback = func;
|
display->priv->generic_callback = func;
|
||||||
gst_gl_window_send_message (display->gl_window,
|
|
||||||
|
gst_gl_window_send_message (display->priv->window,
|
||||||
GST_GL_WINDOW_CB (gst_gl_display_thread_run_generic), display);
|
GST_GL_WINDOW_CB (gst_gl_display_thread_run_generic), display);
|
||||||
|
|
||||||
gst_gl_display_unlock (display);
|
gst_gl_display_unlock (display);
|
||||||
}
|
}
|
||||||
|
|
||||||
guintptr
|
guintptr
|
||||||
gst_gl_display_get_internal_gl_context (GstGLDisplay * display)
|
gst_gl_display_get_internal_gl_context (GstGLDisplay * display)
|
||||||
{
|
{
|
||||||
gulong external_gl_context = 0;
|
g_return_val_if_fail (GST_IS_GL_DISPLAY (display), 0);
|
||||||
gst_gl_display_lock (display);
|
g_return_val_if_fail (GST_GL_IS_WINDOW (display->priv->window), 0);
|
||||||
external_gl_context = gst_gl_window_get_gl_context (display->gl_window);
|
|
||||||
gst_gl_display_unlock (display);
|
return gst_gl_window_get_gl_context (display->priv->window);
|
||||||
return external_gl_context;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gst_gl_display_activate_gl_context (GstGLDisplay * display, gboolean activate)
|
gst_gl_display_activate_gl_context (GstGLDisplay * display, gboolean activate)
|
||||||
{
|
{
|
||||||
|
g_return_if_fail (GST_IS_GL_DISPLAY (display));
|
||||||
|
g_return_if_fail (GST_GL_IS_WINDOW (display->priv->window));
|
||||||
|
|
||||||
if (!activate)
|
if (!activate)
|
||||||
gst_gl_display_lock (display);
|
gst_gl_display_lock (display);
|
||||||
gst_gl_window_activate (display->gl_window, activate);
|
|
||||||
|
gst_gl_window_activate (display->priv->window, activate);
|
||||||
|
|
||||||
if (activate)
|
if (activate)
|
||||||
gst_gl_display_unlock (display);
|
gst_gl_display_unlock (display);
|
||||||
}
|
}
|
||||||
|
|
||||||
GstGLAPI
|
|
||||||
gst_gl_display_get_gl_api_unlocked (GstGLDisplay * display)
|
|
||||||
{
|
|
||||||
return display->gl_api;
|
|
||||||
}
|
|
||||||
|
|
||||||
GstGLAPI
|
GstGLAPI
|
||||||
gst_gl_display_get_gl_api (GstGLDisplay * display)
|
gst_gl_display_get_gl_api (GstGLDisplay * display)
|
||||||
{
|
{
|
||||||
GstGLAPI api;
|
g_return_val_if_fail (GST_IS_GL_DISPLAY (display), GST_GL_API_NONE);
|
||||||
|
|
||||||
gst_gl_display_lock (display);
|
return display->gl_api;
|
||||||
api = gst_gl_display_get_gl_api_unlocked (display);
|
|
||||||
gst_gl_display_unlock (display);
|
|
||||||
|
|
||||||
return api;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gpointer
|
gpointer
|
||||||
|
@ -554,13 +228,50 @@ gst_gl_display_get_gl_vtable (GstGLDisplay * display)
|
||||||
{
|
{
|
||||||
gpointer gl;
|
gpointer gl;
|
||||||
|
|
||||||
gst_gl_display_lock (display);
|
g_return_val_if_fail (GST_IS_GL_DISPLAY (display), NULL);
|
||||||
|
|
||||||
gl = display->gl_vtable;
|
gl = display->gl_vtable;
|
||||||
gst_gl_display_unlock (display);
|
|
||||||
|
|
||||||
return gl;
|
return gl;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------
|
void
|
||||||
//------------------------ END PUBLIC ------------------------
|
gst_gl_display_set_window (GstGLDisplay * display, GstGLWindow * window)
|
||||||
//------------------------------------------------------------
|
{
|
||||||
|
g_return_if_fail (GST_IS_GL_DISPLAY (display));
|
||||||
|
g_return_if_fail (GST_GL_IS_WINDOW (window));
|
||||||
|
|
||||||
|
gst_gl_display_lock (display);
|
||||||
|
|
||||||
|
if (display->priv->window)
|
||||||
|
gst_object_unref (display->priv->window);
|
||||||
|
|
||||||
|
display->priv->window = gst_object_ref (window);
|
||||||
|
|
||||||
|
gst_gl_display_unlock (display);
|
||||||
|
}
|
||||||
|
|
||||||
|
GstGLWindow *
|
||||||
|
gst_gl_display_get_window (GstGLDisplay * display)
|
||||||
|
{
|
||||||
|
GstGLWindow *window;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_GL_DISPLAY (display), NULL);
|
||||||
|
|
||||||
|
gst_gl_display_lock (display);
|
||||||
|
|
||||||
|
window =
|
||||||
|
display->priv->window ? gst_object_ref (display->priv->window) : NULL;
|
||||||
|
|
||||||
|
gst_gl_display_unlock (display);
|
||||||
|
|
||||||
|
return window;
|
||||||
|
}
|
||||||
|
|
||||||
|
GstGLWindow *
|
||||||
|
gst_gl_display_get_window_unlocked (GstGLDisplay * display)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GST_IS_GL_DISPLAY (display), NULL);
|
||||||
|
|
||||||
|
return display->priv->window ? gst_object_ref (display->priv->window) : NULL;
|
||||||
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <gst/video/video.h>
|
#include <gst/video/video.h>
|
||||||
|
|
||||||
typedef struct _GstGLShader GstGLShader;
|
typedef struct _GstGLShader GstGLShader;
|
||||||
|
typedef struct _GstGLWindow GstGLWindow;
|
||||||
|
|
||||||
#include "gstglwindow.h"
|
#include "gstglwindow.h"
|
||||||
#include "gstglshader.h"
|
#include "gstglshader.h"
|
||||||
|
@ -89,12 +90,6 @@ struct _GstGLDisplay
|
||||||
/* thread safe */
|
/* thread safe */
|
||||||
GMutex mutex;
|
GMutex mutex;
|
||||||
|
|
||||||
/* gl context */
|
|
||||||
GThread *gl_thread;
|
|
||||||
GstGLWindow *gl_window;
|
|
||||||
gboolean isAlive;
|
|
||||||
gboolean context_created;
|
|
||||||
|
|
||||||
/* gl API we are using */
|
/* gl API we are using */
|
||||||
GstGLAPI gl_api;
|
GstGLAPI gl_api;
|
||||||
/* foreign gl context */
|
/* foreign gl context */
|
||||||
|
@ -115,9 +110,6 @@ struct _GstGLDisplayClass
|
||||||
|
|
||||||
GstGLDisplay *gst_gl_display_new (void);
|
GstGLDisplay *gst_gl_display_new (void);
|
||||||
|
|
||||||
gboolean gst_gl_display_create_context (GstGLDisplay * display,
|
|
||||||
gulong external_gl_context);
|
|
||||||
|
|
||||||
void gst_gl_display_thread_add (GstGLDisplay * display,
|
void gst_gl_display_thread_add (GstGLDisplay * display,
|
||||||
GstGLDisplayThreadFunc func, gpointer data);
|
GstGLDisplayThreadFunc func, gpointer data);
|
||||||
|
|
||||||
|
@ -126,15 +118,17 @@ void gst_gl_display_activate_gl_context (GstGLDisplay * display, gboolean activa
|
||||||
|
|
||||||
/* Must be called inside a lock/unlock on display, or within the glthread */
|
/* Must be called inside a lock/unlock on display, or within the glthread */
|
||||||
void gst_gl_display_set_error (GstGLDisplay * display, const char * format, ...);
|
void gst_gl_display_set_error (GstGLDisplay * display, const char * format, ...);
|
||||||
gboolean gst_gl_display_check_framebuffer_status (GstGLDisplay * display);
|
|
||||||
|
|
||||||
void gst_gl_display_lock (GstGLDisplay * display);
|
void gst_gl_display_lock (GstGLDisplay * display);
|
||||||
void gst_gl_display_unlock (GstGLDisplay * display);
|
void gst_gl_display_unlock (GstGLDisplay * display);
|
||||||
GstGLAPI gst_gl_display_get_gl_api (GstGLDisplay * display);
|
GstGLAPI gst_gl_display_get_gl_api (GstGLDisplay * display);
|
||||||
GstGLAPI gst_gl_display_get_gl_api_unlocked (GstGLDisplay * display);
|
|
||||||
|
|
||||||
gpointer gst_gl_display_get_gl_vtable (GstGLDisplay * display);
|
gpointer gst_gl_display_get_gl_vtable (GstGLDisplay * display);
|
||||||
|
|
||||||
|
void gst_gl_display_set_window (GstGLDisplay * display, GstGLWindow * window);
|
||||||
|
GstGLWindow * gst_gl_display_get_window (GstGLDisplay * display);
|
||||||
|
GstGLWindow * gst_gl_display_get_window_unlocked (GstGLDisplay * display);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GST_GL_H__ */
|
#endif /* __GST_GL_H__ */
|
||||||
|
|
|
@ -43,11 +43,11 @@
|
||||||
* calling thread.
|
* calling thread.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define USING_OPENGL(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_OPENGL)
|
#define USING_OPENGL(display) (gst_gl_display_get_gl_api (display) & GST_GL_API_OPENGL)
|
||||||
#define USING_OPENGL3(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_OPENGL3)
|
#define USING_OPENGL3(display) (gst_gl_display_get_gl_api (display) & GST_GL_API_OPENGL3)
|
||||||
#define USING_GLES(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_GLES)
|
#define USING_GLES(display) (gst_gl_display_get_gl_api (display) & GST_GL_API_GLES)
|
||||||
#define USING_GLES2(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_GLES2)
|
#define USING_GLES2(display) (gst_gl_display_get_gl_api (display) & GST_GL_API_GLES2)
|
||||||
#define USING_GLES3(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_GLES3)
|
#define USING_GLES3(display) (gst_gl_display_get_gl_api (display) & GST_GL_API_GLES3)
|
||||||
|
|
||||||
static void _do_download (GstGLDisplay * display, GstGLDownload * download);
|
static void _do_download (GstGLDisplay * display, GstGLDownload * download);
|
||||||
static void _init_download (GstGLDisplay * display, GstGLDownload * download);
|
static void _init_download (GstGLDisplay * display, GstGLDownload * download);
|
||||||
|
|
|
@ -150,6 +150,7 @@ _gst_gl_feature_check (GstGLDisplay * display,
|
||||||
const char *suffix = NULL;
|
const char *suffix = NULL;
|
||||||
int func_num;
|
int func_num;
|
||||||
GstGLFuncs *gst_gl = display->gl_vtable;
|
GstGLFuncs *gst_gl = display->gl_vtable;
|
||||||
|
GstGLWindow *window = NULL;
|
||||||
|
|
||||||
/* First check whether the functions should be directly provided by
|
/* First check whether the functions should be directly provided by
|
||||||
GL */
|
GL */
|
||||||
|
@ -172,6 +173,9 @@ _gst_gl_feature_check (GstGLDisplay * display,
|
||||||
if (suffix == NULL)
|
if (suffix == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
window = gst_gl_display_get_window (display);
|
||||||
|
g_assert (window);
|
||||||
|
|
||||||
/* Try to get all of the entry points */
|
/* Try to get all of the entry points */
|
||||||
for (func_num = 0; data->functions[func_num].name; func_num++) {
|
for (func_num = 0; data->functions[func_num].name; func_num++) {
|
||||||
void *func;
|
void *func;
|
||||||
|
@ -183,8 +187,7 @@ _gst_gl_feature_check (GstGLDisplay * display,
|
||||||
suffix, NULL);
|
suffix, NULL);
|
||||||
GST_TRACE ("%s should %sbe in core", full_function_name,
|
GST_TRACE ("%s should %sbe in core", full_function_name,
|
||||||
in_core ? "" : "not ");
|
in_core ? "" : "not ");
|
||||||
func =
|
func = gst_gl_window_get_proc_address (window, full_function_name);
|
||||||
gst_gl_window_get_proc_address (display->gl_window, full_function_name);
|
|
||||||
|
|
||||||
if (func == NULL && in_core) {
|
if (func == NULL && in_core) {
|
||||||
GST_TRACE ("%s was not found in core, trying the extension version",
|
GST_TRACE ("%s was not found in core, trying the extension version",
|
||||||
|
@ -196,8 +199,7 @@ _gst_gl_feature_check (GstGLDisplay * display,
|
||||||
g_free (full_function_name);
|
g_free (full_function_name);
|
||||||
full_function_name = g_strconcat ("gl", data->functions[func_num].name,
|
full_function_name = g_strconcat ("gl", data->functions[func_num].name,
|
||||||
suffix, NULL);
|
suffix, NULL);
|
||||||
func = gst_gl_window_get_proc_address (display->gl_window,
|
func = gst_gl_window_get_proc_address (window, full_function_name);
|
||||||
full_function_name);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,6 +214,7 @@ _gst_gl_feature_check (GstGLDisplay * display,
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free (full_function_name);
|
g_free (full_function_name);
|
||||||
|
gst_object_unref (window);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
@ -230,6 +233,9 @@ error:
|
||||||
g_free (full_function_name);
|
g_free (full_function_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (window)
|
||||||
|
gst_object_unref (window);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -253,11 +253,18 @@ gst_gl_filter_start (GstBaseTransform * bt)
|
||||||
filter->display =
|
filter->display =
|
||||||
g_object_ref (GST_GL_DISPLAY (g_value_get_pointer (id_value)));
|
g_object_ref (GST_GL_DISPLAY (g_value_get_pointer (id_value)));
|
||||||
else {
|
else {
|
||||||
|
GstGLWindow *window;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
GST_INFO ("Creating GstGLDisplay");
|
GST_INFO ("Creating GstGLDisplay");
|
||||||
filter->display = gst_gl_display_new ();
|
filter->display = gst_gl_display_new ();
|
||||||
if (!gst_gl_display_create_context (filter->display, 0)) {
|
window = gst_gl_window_new (filter->display);
|
||||||
|
gst_gl_display_set_window (filter->display, window);
|
||||||
|
g_object_unref (window);
|
||||||
|
|
||||||
|
if (!gst_gl_window_create_context (window, 0, &error)) {
|
||||||
GST_ELEMENT_ERROR (filter, RESOURCE, NOT_FOUND,
|
GST_ELEMENT_ERROR (filter, RESOURCE, NOT_FOUND,
|
||||||
GST_GL_DISPLAY_ERR_MSG (filter->display), (NULL));
|
("%s", error->message), (NULL));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -727,9 +734,10 @@ gst_gl_filter_set_caps (GstBaseTransform * bt, GstCaps * incaps,
|
||||||
if (filter_class->display_init_cb != NULL) {
|
if (filter_class->display_init_cb != NULL) {
|
||||||
gst_gl_display_thread_add (filter->display, gst_gl_filter_start_gl, filter);
|
gst_gl_display_thread_add (filter->display, gst_gl_filter_start_gl, filter);
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
if (!filter->display->isAlive)
|
if (!filter->display->isAlive)
|
||||||
goto error;
|
goto error;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (filter_class->onInitFBO) {
|
if (filter_class->onInitFBO) {
|
||||||
if (!filter_class->onInitFBO (filter))
|
if (!filter_class->onInitFBO (filter))
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <gst/video/video.h>
|
#include <gst/video/video.h>
|
||||||
|
|
||||||
#include "gstglmemory.h"
|
#include "gstglmemory.h"
|
||||||
|
#include "gstglutils.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION:gstglmemory
|
* SECTION:gstglmemory
|
||||||
|
|
|
@ -935,11 +935,18 @@ gst_gl_mixer_activate (GstGLMixer * mix, gboolean activate)
|
||||||
mix->display =
|
mix->display =
|
||||||
g_object_ref (GST_GL_DISPLAY (g_value_get_pointer (id_value)));
|
g_object_ref (GST_GL_DISPLAY (g_value_get_pointer (id_value)));
|
||||||
else {
|
else {
|
||||||
|
GstGLWindow *window;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
GST_INFO ("Creating GstGLDisplay");
|
GST_INFO ("Creating GstGLDisplay");
|
||||||
mix->display = gst_gl_display_new ();
|
mix->display = gst_gl_display_new ();
|
||||||
if (!gst_gl_display_create_context (mix->display, 0)) {
|
window = gst_gl_window_new (mix->display);
|
||||||
|
gst_gl_display_set_window (mix->display, window);
|
||||||
|
g_object_unref (window);
|
||||||
|
|
||||||
|
if (!gst_gl_window_create_context (window, 0, &error)) {
|
||||||
GST_ELEMENT_ERROR (mix, RESOURCE, NOT_FOUND,
|
GST_ELEMENT_ERROR (mix, RESOURCE, NOT_FOUND,
|
||||||
GST_GL_DISPLAY_ERR_MSG (mix->display), (NULL));
|
("%s", error->message), (NULL));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,11 +43,11 @@
|
||||||
* calling thread.
|
* calling thread.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define USING_OPENGL(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_OPENGL)
|
#define USING_OPENGL(display) (gst_gl_display_get_gl_api (display) & GST_GL_API_OPENGL)
|
||||||
#define USING_OPENGL3(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_OPENGL3)
|
#define USING_OPENGL3(display) (gst_gl_display_get_gl_api (display) & GST_GL_API_OPENGL3)
|
||||||
#define USING_GLES(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_GLES)
|
#define USING_GLES(display) (gst_gl_display_get_gl_api (display) & GST_GL_API_GLES)
|
||||||
#define USING_GLES2(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_GLES2)
|
#define USING_GLES2(display) (gst_gl_display_get_gl_api (display) & GST_GL_API_GLES2)
|
||||||
#define USING_GLES3(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_GLES3)
|
#define USING_GLES3(display) (gst_gl_display_get_gl_api (display) & GST_GL_API_GLES3)
|
||||||
|
|
||||||
static void _do_upload (GstGLDisplay * display, GstGLUpload * upload);
|
static void _do_upload (GstGLDisplay * display, GstGLUpload * upload);
|
||||||
static void _do_upload_fill (GstGLDisplay * display, GstGLUpload * upload);
|
static void _do_upload_fill (GstGLDisplay * display, GstGLUpload * upload);
|
||||||
|
|
|
@ -234,18 +234,24 @@ void
|
||||||
gst_gl_display_gen_texture (GstGLDisplay * display, GLuint * pTexture,
|
gst_gl_display_gen_texture (GstGLDisplay * display, GLuint * pTexture,
|
||||||
GstVideoFormat v_format, GLint width, GLint height)
|
GstVideoFormat v_format, GLint width, GLint height)
|
||||||
{
|
{
|
||||||
|
GstGLWindow *window;
|
||||||
|
|
||||||
gst_gl_display_lock (display);
|
gst_gl_display_lock (display);
|
||||||
|
|
||||||
if (display->isAlive) {
|
window = gst_gl_display_get_window_unlocked (display);
|
||||||
|
|
||||||
|
if (gst_gl_window_is_running (window)) {
|
||||||
gen_texture_width = width;
|
gen_texture_width = width;
|
||||||
gen_texture_height = height;
|
gen_texture_height = height;
|
||||||
gen_texture_video_format = v_format;
|
gen_texture_video_format = v_format;
|
||||||
gst_gl_window_send_message (display->gl_window,
|
gst_gl_window_send_message (window,
|
||||||
GST_GL_WINDOW_CB (gst_gl_display_gen_texture_window_cb), display);
|
GST_GL_WINDOW_CB (gst_gl_display_gen_texture_window_cb), display);
|
||||||
*pTexture = gen_texture;
|
*pTexture = gen_texture;
|
||||||
} else
|
} else
|
||||||
*pTexture = 0;
|
*pTexture = 0;
|
||||||
|
|
||||||
|
gst_object_unref (window);
|
||||||
|
|
||||||
gst_gl_display_unlock (display);
|
gst_gl_display_unlock (display);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,21 +269,26 @@ gboolean
|
||||||
gst_gl_display_gen_fbo (GstGLDisplay * display, gint width, gint height,
|
gst_gl_display_gen_fbo (GstGLDisplay * display, gint width, gint height,
|
||||||
GLuint * fbo, GLuint * depthbuffer)
|
GLuint * fbo, GLuint * depthbuffer)
|
||||||
{
|
{
|
||||||
gboolean isAlive = FALSE;
|
gboolean alive = FALSE;
|
||||||
|
GstGLWindow *window;
|
||||||
|
|
||||||
gst_gl_display_lock (display);
|
gst_gl_display_lock (display);
|
||||||
if (display->isAlive) {
|
|
||||||
|
window = gst_gl_display_get_window_unlocked (display);
|
||||||
|
|
||||||
|
if (gst_gl_window_is_running (window)) {
|
||||||
gen_fbo_width = width;
|
gen_fbo_width = width;
|
||||||
gen_fbo_height = height;
|
gen_fbo_height = height;
|
||||||
gst_gl_window_send_message (display->gl_window, GST_GL_WINDOW_CB (_gen_fbo),
|
gst_gl_window_send_message (window, GST_GL_WINDOW_CB (_gen_fbo), display);
|
||||||
display);
|
|
||||||
*fbo = generated_fbo;
|
*fbo = generated_fbo;
|
||||||
*depthbuffer = generated_depth_buffer;
|
*depthbuffer = generated_depth_buffer;
|
||||||
}
|
}
|
||||||
isAlive = display->isAlive;
|
alive = gst_gl_window_is_running (window);
|
||||||
|
|
||||||
|
gst_object_unref (window);
|
||||||
gst_gl_display_unlock (display);
|
gst_gl_display_unlock (display);
|
||||||
|
|
||||||
return isAlive;
|
return alive;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -297,10 +308,13 @@ gst_gl_display_use_fbo (GstGLDisplay * display, gint texture_fbo_width,
|
||||||
gdouble proj_param2, gdouble proj_param3, gdouble proj_param4,
|
gdouble proj_param2, gdouble proj_param3, gdouble proj_param4,
|
||||||
GstGLDisplayProjection projection, gpointer * stuff)
|
GstGLDisplayProjection projection, gpointer * stuff)
|
||||||
{
|
{
|
||||||
gboolean isAlive;
|
gboolean alive;
|
||||||
|
GstGLWindow *window;
|
||||||
|
|
||||||
gst_gl_display_lock (display);
|
gst_gl_display_lock (display);
|
||||||
if (display->isAlive) {
|
|
||||||
|
window = gst_gl_display_get_window_unlocked (display);
|
||||||
|
if (gst_gl_window_is_running (window)) {
|
||||||
use_fbo = fbo;
|
use_fbo = fbo;
|
||||||
use_depth_buffer = depth_buffer;
|
use_depth_buffer = depth_buffer;
|
||||||
use_fbo_texture = texture_fbo;
|
use_fbo_texture = texture_fbo;
|
||||||
|
@ -316,13 +330,14 @@ gst_gl_display_use_fbo (GstGLDisplay * display, gint texture_fbo_width,
|
||||||
input_texture_width = input_tex_width;
|
input_texture_width = input_tex_width;
|
||||||
input_texture_height = input_tex_height;
|
input_texture_height = input_tex_height;
|
||||||
input_texture = input_tex;
|
input_texture = input_tex;
|
||||||
gst_gl_window_send_message (display->gl_window, GST_GL_WINDOW_CB (_use_fbo),
|
gst_gl_window_send_message (window, GST_GL_WINDOW_CB (_use_fbo), display);
|
||||||
display);
|
|
||||||
}
|
}
|
||||||
isAlive = display->isAlive;
|
alive = gst_gl_window_is_running (window);
|
||||||
|
|
||||||
|
gst_object_unref (window);
|
||||||
gst_gl_display_unlock (display);
|
gst_gl_display_unlock (display);
|
||||||
|
|
||||||
return isAlive;
|
return alive;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
|
@ -330,10 +345,13 @@ gst_gl_display_use_fbo_v2 (GstGLDisplay * display, gint texture_fbo_width,
|
||||||
gint texture_fbo_height, GLuint fbo, GLuint depth_buffer,
|
gint texture_fbo_height, GLuint fbo, GLuint depth_buffer,
|
||||||
GLuint texture_fbo, GLCB_V2 cb, gpointer * stuff)
|
GLuint texture_fbo, GLCB_V2 cb, gpointer * stuff)
|
||||||
{
|
{
|
||||||
gboolean isAlive;
|
gboolean alive;
|
||||||
|
GstGLWindow *window;
|
||||||
|
|
||||||
gst_gl_display_lock (display);
|
gst_gl_display_lock (display);
|
||||||
if (display->isAlive) {
|
|
||||||
|
window = gst_gl_display_get_window_unlocked (display);
|
||||||
|
if (gst_gl_window_is_running (window)) {
|
||||||
use_fbo = fbo;
|
use_fbo = fbo;
|
||||||
use_depth_buffer = depth_buffer;
|
use_depth_buffer = depth_buffer;
|
||||||
use_fbo_texture = texture_fbo;
|
use_fbo_texture = texture_fbo;
|
||||||
|
@ -341,26 +359,33 @@ gst_gl_display_use_fbo_v2 (GstGLDisplay * display, gint texture_fbo_width,
|
||||||
use_fbo_height = texture_fbo_height;
|
use_fbo_height = texture_fbo_height;
|
||||||
use_fbo_scene_cb_v2 = cb;
|
use_fbo_scene_cb_v2 = cb;
|
||||||
use_fbo_stuff = stuff;
|
use_fbo_stuff = stuff;
|
||||||
gst_gl_window_send_message (display->gl_window,
|
gst_gl_window_send_message (window,
|
||||||
GST_GL_WINDOW_CB (_use_fbo_v2), display);
|
GST_GL_WINDOW_CB (_use_fbo_v2), display);
|
||||||
}
|
}
|
||||||
isAlive = display->isAlive;
|
alive = gst_gl_window_is_running (window);
|
||||||
|
|
||||||
|
gst_object_unref (window);
|
||||||
gst_gl_display_unlock (display);
|
gst_gl_display_unlock (display);
|
||||||
|
|
||||||
return isAlive;
|
return alive;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called by gltestsrc and glfilter */
|
/* Called by gltestsrc and glfilter */
|
||||||
void
|
void
|
||||||
gst_gl_display_del_fbo (GstGLDisplay * display, GLuint fbo, GLuint depth_buffer)
|
gst_gl_display_del_fbo (GstGLDisplay * display, GLuint fbo, GLuint depth_buffer)
|
||||||
{
|
{
|
||||||
|
GstGLWindow *window;
|
||||||
|
|
||||||
gst_gl_display_lock (display);
|
gst_gl_display_lock (display);
|
||||||
if (display->isAlive) {
|
|
||||||
|
window = gst_gl_display_get_window_unlocked (display);
|
||||||
|
if (gst_gl_window_is_running (window)) {
|
||||||
del_fbo = fbo;
|
del_fbo = fbo;
|
||||||
del_depth_buffer = depth_buffer;
|
del_depth_buffer = depth_buffer;
|
||||||
gst_gl_window_send_message (display->gl_window, GST_GL_WINDOW_CB (_del_fbo),
|
gst_gl_window_send_message (window, GST_GL_WINDOW_CB (_del_fbo), display);
|
||||||
display);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gst_object_unref (window);
|
||||||
gst_gl_display_unlock (display);
|
gst_gl_display_unlock (display);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,13 +396,16 @@ gst_gl_display_gen_shader (GstGLDisplay * display,
|
||||||
const gchar * shader_vertex_source,
|
const gchar * shader_vertex_source,
|
||||||
const gchar * shader_fragment_source, GstGLShader ** shader)
|
const gchar * shader_fragment_source, GstGLShader ** shader)
|
||||||
{
|
{
|
||||||
gboolean isAlive;
|
gboolean alive;
|
||||||
|
GstGLWindow *window;
|
||||||
|
|
||||||
gst_gl_display_lock (display);
|
gst_gl_display_lock (display);
|
||||||
if (display->isAlive) {
|
|
||||||
|
window = gst_gl_display_get_window_unlocked (display);
|
||||||
|
if (gst_gl_window_is_running (window)) {
|
||||||
gen_shader_vertex_source = shader_vertex_source;
|
gen_shader_vertex_source = shader_vertex_source;
|
||||||
gen_shader_fragment_source = shader_fragment_source;
|
gen_shader_fragment_source = shader_fragment_source;
|
||||||
gst_gl_window_send_message (display->gl_window,
|
gst_gl_window_send_message (window,
|
||||||
GST_GL_WINDOW_CB (_gen_shader), display);
|
GST_GL_WINDOW_CB (_gen_shader), display);
|
||||||
if (shader)
|
if (shader)
|
||||||
*shader = gen_shader;
|
*shader = gen_shader;
|
||||||
|
@ -385,10 +413,12 @@ gst_gl_display_gen_shader (GstGLDisplay * display,
|
||||||
gen_shader_vertex_source = NULL;
|
gen_shader_vertex_source = NULL;
|
||||||
gen_shader_fragment_source = NULL;
|
gen_shader_fragment_source = NULL;
|
||||||
}
|
}
|
||||||
isAlive = display->isAlive;
|
alive = gst_gl_window_is_running (window);
|
||||||
|
|
||||||
|
gst_object_unref (window);
|
||||||
gst_gl_display_unlock (display);
|
gst_gl_display_unlock (display);
|
||||||
|
|
||||||
return isAlive;
|
return alive;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -396,12 +426,18 @@ gst_gl_display_gen_shader (GstGLDisplay * display,
|
||||||
void
|
void
|
||||||
gst_gl_display_del_shader (GstGLDisplay * display, GstGLShader * shader)
|
gst_gl_display_del_shader (GstGLDisplay * display, GstGLShader * shader)
|
||||||
{
|
{
|
||||||
|
GstGLWindow *window;
|
||||||
|
|
||||||
gst_gl_display_lock (display);
|
gst_gl_display_lock (display);
|
||||||
if (display->isAlive) {
|
|
||||||
|
window = gst_gl_display_get_window_unlocked (display);
|
||||||
|
if (gst_gl_window_is_running (window)) {
|
||||||
del_shader = shader;
|
del_shader = shader;
|
||||||
gst_gl_window_send_message (display->gl_window,
|
gst_gl_window_send_message (window,
|
||||||
GST_GL_WINDOW_CB (_del_shader), display);
|
GST_GL_WINDOW_CB (_del_shader), display);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gst_object_unref (window);
|
||||||
gst_gl_display_unlock (display);
|
gst_gl_display_unlock (display);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,4 +99,6 @@ gboolean gst_gl_display_gen_shader (GstGLDisplay * display,
|
||||||
const gchar * shader_fragment_source, GstGLShader ** shader);
|
const gchar * shader_fragment_source, GstGLShader ** shader);
|
||||||
void gst_gl_display_del_shader (GstGLDisplay * display, GstGLShader * shader);
|
void gst_gl_display_del_shader (GstGLDisplay * display, GstGLShader * shader);
|
||||||
|
|
||||||
|
gboolean gst_gl_display_check_framebuffer_status (GstGLDisplay * display);
|
||||||
|
|
||||||
#endif /* __GST_GL_UTILS_H__ */
|
#endif /* __GST_GL_UTILS_H__ */
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <gmodule.h>
|
#include <gmodule.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "gstglwindow.h"
|
#include "gstglwindow.h"
|
||||||
|
|
||||||
|
@ -39,12 +40,45 @@
|
||||||
#include "wayland/gstglwindow_wayland_egl.h"
|
#include "wayland/gstglwindow_wayland_egl.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "gstglfeature.h"
|
||||||
|
|
||||||
|
#define USING_OPENGL(display) (display->gl_api & GST_GL_API_OPENGL)
|
||||||
|
#define USING_OPENGL3(display) (display->gl_api & GST_GL_API_OPENGL3)
|
||||||
|
#define USING_GLES(display) (display->gl_api & GST_GL_API_GLES)
|
||||||
|
#define USING_GLES2(display) (display->gl_api & GST_GL_API_GLES2)
|
||||||
|
#define USING_GLES3(display) (display->gl_api & GST_GL_API_GLES3)
|
||||||
|
|
||||||
#define GST_CAT_DEFAULT gst_gl_window_debug
|
#define GST_CAT_DEFAULT gst_gl_window_debug
|
||||||
GST_DEBUG_CATEGORY (GST_CAT_DEFAULT);
|
GST_DEBUG_CATEGORY (GST_CAT_DEFAULT);
|
||||||
|
|
||||||
#define gst_gl_window_parent_class parent_class
|
#define gst_gl_window_parent_class parent_class
|
||||||
G_DEFINE_ABSTRACT_TYPE (GstGLWindow, gst_gl_window, G_TYPE_OBJECT);
|
G_DEFINE_ABSTRACT_TYPE (GstGLWindow, gst_gl_window, G_TYPE_OBJECT);
|
||||||
|
|
||||||
|
#define GST_GL_WINDOW_GET_PRIVATE(o) \
|
||||||
|
(G_TYPE_INSTANCE_GET_PRIVATE((o), GST_GL_TYPE_WINDOW, GstGLWindowPrivate))
|
||||||
|
|
||||||
|
struct _GstGLWindowPrivate
|
||||||
|
{
|
||||||
|
GstGLDisplay *display;
|
||||||
|
|
||||||
|
GThread *gl_thread;
|
||||||
|
|
||||||
|
/* conditions */
|
||||||
|
GMutex render_lock;
|
||||||
|
GCond cond_create_context;
|
||||||
|
GCond cond_destroy_context;
|
||||||
|
|
||||||
|
gboolean context_created;
|
||||||
|
gboolean alive;
|
||||||
|
|
||||||
|
guintptr external_gl_context;
|
||||||
|
GstGLAPI gl_api;
|
||||||
|
GError **error;
|
||||||
|
};
|
||||||
|
|
||||||
|
static gpointer _gst_gl_window_thread_create_context (GstGLWindow * window);
|
||||||
|
static void gst_gl_window_finalize (GObject * object);
|
||||||
|
|
||||||
GQuark
|
GQuark
|
||||||
gst_gl_window_error_quark (void)
|
gst_gl_window_error_quark (void)
|
||||||
{
|
{
|
||||||
|
@ -54,19 +88,30 @@ gst_gl_window_error_quark (void)
|
||||||
static void
|
static void
|
||||||
gst_gl_window_init (GstGLWindow * window)
|
gst_gl_window_init (GstGLWindow * window)
|
||||||
{
|
{
|
||||||
|
window->priv = GST_GL_WINDOW_GET_PRIVATE (window);
|
||||||
|
|
||||||
g_mutex_init (&window->lock);
|
g_mutex_init (&window->lock);
|
||||||
window->need_lock = TRUE;
|
window->need_lock = TRUE;
|
||||||
|
|
||||||
|
g_mutex_init (&window->priv->render_lock);
|
||||||
|
g_cond_init (&window->priv->cond_create_context);
|
||||||
|
g_cond_init (&window->priv->cond_destroy_context);
|
||||||
|
window->priv->context_created = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_gl_window_class_init (GstGLWindowClass * klass)
|
gst_gl_window_class_init (GstGLWindowClass * klass)
|
||||||
{
|
{
|
||||||
|
g_type_class_add_private (klass, sizeof (GstGLWindowPrivate));
|
||||||
|
|
||||||
klass->get_proc_address =
|
klass->get_proc_address =
|
||||||
GST_DEBUG_FUNCPTR (gst_gl_window_default_get_proc_address);
|
GST_DEBUG_FUNCPTR (gst_gl_window_default_get_proc_address);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (klass)->finalize = gst_gl_window_finalize;
|
||||||
}
|
}
|
||||||
|
|
||||||
GstGLWindow *
|
GstGLWindow *
|
||||||
gst_gl_window_new (void)
|
gst_gl_window_new (GstGLDisplay * display)
|
||||||
{
|
{
|
||||||
GstGLWindow *window = NULL;
|
GstGLWindow *window = NULL;
|
||||||
const gchar *user_choice;
|
const gchar *user_choice;
|
||||||
|
@ -106,9 +151,43 @@ gst_gl_window_new (void)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window->priv->display = display;
|
||||||
|
|
||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_gl_window_finalize (GObject * object)
|
||||||
|
{
|
||||||
|
GstGLWindow *window = GST_GL_WINDOW (object);
|
||||||
|
|
||||||
|
if (window) {
|
||||||
|
gst_gl_window_set_resize_callback (window, NULL, NULL);
|
||||||
|
gst_gl_window_set_draw_callback (window, NULL, NULL);
|
||||||
|
gst_gl_window_set_close_callback (window, NULL, NULL);
|
||||||
|
|
||||||
|
if (window->priv->alive) {
|
||||||
|
GST_INFO ("send quit gl window loop");
|
||||||
|
gst_gl_window_quit (window, NULL, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window->priv->gl_thread) {
|
||||||
|
gpointer ret = g_thread_join (window->priv->gl_thread);
|
||||||
|
GST_INFO ("gl thread joined");
|
||||||
|
if (ret != NULL)
|
||||||
|
GST_ERROR ("gl thread returned a non-null pointer");
|
||||||
|
window->priv->gl_thread = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_mutex_clear (&window->priv->render_lock);
|
||||||
|
|
||||||
|
g_cond_clear (&window->priv->cond_destroy_context);
|
||||||
|
g_cond_clear (&window->priv->cond_create_context);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (gst_gl_window_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
guintptr
|
guintptr
|
||||||
gst_gl_window_get_gl_context (GstGLWindow * window)
|
gst_gl_window_get_gl_context (GstGLWindow * window)
|
||||||
{
|
{
|
||||||
|
@ -209,10 +288,17 @@ gst_gl_window_quit (GstGLWindow * window, GstGLWindowCB callback, gpointer data)
|
||||||
|
|
||||||
GST_GL_WINDOW_LOCK (window);
|
GST_GL_WINDOW_LOCK (window);
|
||||||
|
|
||||||
|
window->priv->alive = FALSE;
|
||||||
|
|
||||||
window->close = callback;
|
window->close = callback;
|
||||||
window->close_data = data;
|
window->close_data = data;
|
||||||
window_class->quit (window, callback, data);
|
window_class->quit (window, callback, data);
|
||||||
|
|
||||||
|
GST_INFO ("quit sent to gl window loop");
|
||||||
|
|
||||||
|
g_cond_wait (&window->priv->cond_destroy_context, &window->priv->render_lock);
|
||||||
|
GST_INFO ("quit received from gl window");
|
||||||
|
|
||||||
GST_GL_WINDOW_UNLOCK (window);
|
GST_GL_WINDOW_UNLOCK (window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,7 +417,7 @@ gst_gl_window_get_proc_address (GstGLWindow * window, const gchar * name)
|
||||||
|
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_gl_window_create_context (GstGLWindow * window, GstGLAPI gl_api,
|
_priv_gst_gl_window_create_context (GstGLWindow * window, GstGLAPI gl_api,
|
||||||
guintptr external_gl_context, GError ** error)
|
guintptr external_gl_context, GError ** error)
|
||||||
{
|
{
|
||||||
gboolean ret;
|
gboolean ret;
|
||||||
|
@ -368,3 +454,309 @@ gst_gl_window_default_get_proc_address (GstGLWindow * window,
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Create an opengl context (one context for one GstGLDisplay) */
|
||||||
|
gboolean
|
||||||
|
gst_gl_window_create_context (GstGLWindow * window,
|
||||||
|
guintptr external_gl_context, GError ** error)
|
||||||
|
{
|
||||||
|
gboolean alive = FALSE;
|
||||||
|
GstGLWindowClass *window_class;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_GL_IS_WINDOW (window), FALSE);
|
||||||
|
window_class = GST_GL_WINDOW_GET_CLASS (window);
|
||||||
|
g_return_val_if_fail (window_class->create_context != NULL, FALSE);
|
||||||
|
|
||||||
|
g_mutex_lock (&window->priv->render_lock);
|
||||||
|
|
||||||
|
if (!window->priv->context_created) {
|
||||||
|
window->priv->external_gl_context = external_gl_context;
|
||||||
|
window->priv->error = error;
|
||||||
|
|
||||||
|
window->priv->gl_thread = g_thread_new ("gstglcontext",
|
||||||
|
(GThreadFunc) _gst_gl_window_thread_create_context, window);
|
||||||
|
|
||||||
|
g_cond_wait (&window->priv->cond_create_context,
|
||||||
|
&window->priv->render_lock);
|
||||||
|
|
||||||
|
window->priv->context_created = TRUE;
|
||||||
|
|
||||||
|
GST_INFO ("gl thread created");
|
||||||
|
}
|
||||||
|
|
||||||
|
alive = window->priv->alive;
|
||||||
|
|
||||||
|
g_mutex_unlock (&window->priv->render_lock);
|
||||||
|
|
||||||
|
return alive;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_gl_window_is_running (GstGLWindow * window)
|
||||||
|
{
|
||||||
|
return window->priv->alive;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_create_context_gles2 (GstGLWindow * window, gint * gl_major, gint * gl_minor)
|
||||||
|
{
|
||||||
|
GstGLDisplay *display;
|
||||||
|
const GstGLFuncs *gl;
|
||||||
|
GLenum gl_err = GL_NO_ERROR;
|
||||||
|
GError **error;
|
||||||
|
|
||||||
|
display = window->priv->display;
|
||||||
|
gl = display->gl_vtable;
|
||||||
|
error = window->priv->error;
|
||||||
|
|
||||||
|
GST_INFO ("GL_VERSION: %s", gl->GetString (GL_VERSION));
|
||||||
|
GST_INFO ("GL_SHADING_LANGUAGE_VERSION: %s",
|
||||||
|
gl->GetString (GL_SHADING_LANGUAGE_VERSION));
|
||||||
|
GST_INFO ("GL_VENDOR: %s", gl->GetString (GL_VENDOR));
|
||||||
|
GST_INFO ("GL_RENDERER: %s", gl->GetString (GL_RENDERER));
|
||||||
|
|
||||||
|
gl_err = gl->GetError ();
|
||||||
|
if (gl_err != GL_NO_ERROR) {
|
||||||
|
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_FAILED,
|
||||||
|
"glGetString error: 0x%x", gl_err);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
#if GST_GL_HAVE_GLES2
|
||||||
|
if (!GL_ES_VERSION_2_0) {
|
||||||
|
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_OLD_LIBS,
|
||||||
|
"OpenGL|ES >= 2.0 is required");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_gst_gl_feature_check_ext_functions (display, 0, 0,
|
||||||
|
(const gchar *) gl->GetString (GL_EXTENSIONS));
|
||||||
|
|
||||||
|
if (gl_major)
|
||||||
|
*gl_major = 2;
|
||||||
|
if (gl_minor)
|
||||||
|
*gl_minor = 0;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_create_context_opengl (GstGLWindow * window, gint * gl_major, gint * gl_minor)
|
||||||
|
{
|
||||||
|
GstGLDisplay *display;
|
||||||
|
const GstGLFuncs *gl;
|
||||||
|
guint maj, min;
|
||||||
|
GLenum gl_err = GL_NO_ERROR;
|
||||||
|
GString *opengl_version = NULL;
|
||||||
|
GError **error;
|
||||||
|
|
||||||
|
display = window->priv->display;
|
||||||
|
gl = display->gl_vtable;
|
||||||
|
error = window->priv->error;
|
||||||
|
|
||||||
|
GST_INFO ("GL_VERSION: %s", gl->GetString (GL_VERSION));
|
||||||
|
GST_INFO ("GL_SHADING_LANGUAGE_VERSION: %s",
|
||||||
|
gl->GetString (GL_SHADING_LANGUAGE_VERSION));
|
||||||
|
GST_INFO ("GL_VENDOR: %s", gl->GetString (GL_VENDOR));
|
||||||
|
GST_INFO ("GL_RENDERER: %s", gl->GetString (GL_RENDERER));
|
||||||
|
|
||||||
|
gl_err = gl->GetError ();
|
||||||
|
if (gl_err != GL_NO_ERROR) {
|
||||||
|
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_FAILED,
|
||||||
|
"glGetString error: 0x%x", gl_err);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
opengl_version =
|
||||||
|
g_string_truncate (g_string_new ((gchar *) gl->GetString (GL_VERSION)),
|
||||||
|
3);
|
||||||
|
|
||||||
|
sscanf (opengl_version->str, "%d.%d", &maj, &min);
|
||||||
|
|
||||||
|
g_string_free (opengl_version, TRUE);
|
||||||
|
|
||||||
|
/* OpenGL > 1.2.0 */
|
||||||
|
if ((maj < 1) || (maj < 2 && maj >= 1 && min < 2)) {
|
||||||
|
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_OLD_LIBS,
|
||||||
|
"OpenGL >= 1.2.0 required, found %u.%u", maj, min);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_gst_gl_feature_check_ext_functions (display, maj, min,
|
||||||
|
(const gchar *) gl->GetString (GL_EXTENSIONS));
|
||||||
|
|
||||||
|
if (gl_major)
|
||||||
|
*gl_major = maj;
|
||||||
|
if (gl_minor)
|
||||||
|
*gl_minor = min;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GstGLAPI
|
||||||
|
_compiled_api (void)
|
||||||
|
{
|
||||||
|
GstGLAPI ret = GST_GL_API_NONE;
|
||||||
|
|
||||||
|
#if GST_GL_HAVE_OPENGL
|
||||||
|
ret |= GST_GL_API_OPENGL;
|
||||||
|
#endif
|
||||||
|
#if GST_GL_HAVE_GLES2
|
||||||
|
ret |= GST_GL_API_GLES2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
GstGLAPI
|
||||||
|
_parse_gl_api (const gchar * apis_s)
|
||||||
|
{
|
||||||
|
GstGLAPI ret = GST_GL_API_NONE;
|
||||||
|
gchar *apis = (gchar *) apis_s;
|
||||||
|
|
||||||
|
while (apis) {
|
||||||
|
if (apis[0] == '\0') {
|
||||||
|
break;
|
||||||
|
} else if (apis[0] == ' ' || apis[0] == ',') {
|
||||||
|
apis = &apis[1];
|
||||||
|
} else if (g_strstr_len (apis, 7, "opengl3")) {
|
||||||
|
ret |= GST_GL_API_OPENGL3;
|
||||||
|
apis = &apis[7];
|
||||||
|
} else if (g_strstr_len (apis, 6, "opengl")) {
|
||||||
|
ret |= GST_GL_API_OPENGL;
|
||||||
|
apis = &apis[6];
|
||||||
|
} else if (g_strstr_len (apis, 5, "gles1")) {
|
||||||
|
ret |= GST_GL_API_GLES;
|
||||||
|
apis = &apis[5];
|
||||||
|
} else if (g_strstr_len (apis, 5, "gles2")) {
|
||||||
|
ret |= GST_GL_API_GLES2;
|
||||||
|
apis = &apis[5];
|
||||||
|
} else if (g_strstr_len (apis, 5, "gles3")) {
|
||||||
|
ret |= GST_GL_API_GLES3;
|
||||||
|
apis = &apis[5];
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == GST_GL_API_NONE)
|
||||||
|
ret = GST_GL_API_ANY;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gpointer
|
||||||
|
_gst_gl_window_thread_create_context (GstGLWindow * window)
|
||||||
|
{
|
||||||
|
GstGLWindowClass *window_class;
|
||||||
|
GstGLDisplay *display;
|
||||||
|
GstGLFuncs *gl;
|
||||||
|
gint gl_major = 0;
|
||||||
|
gboolean ret = FALSE;
|
||||||
|
GstGLAPI compiled_api, user_api;
|
||||||
|
gchar *api_string;
|
||||||
|
gchar *compiled_api_s;
|
||||||
|
gchar *user_api_string;
|
||||||
|
const gchar *user_choice;
|
||||||
|
GError **error;
|
||||||
|
|
||||||
|
window_class = GST_GL_WINDOW_GET_CLASS (window);
|
||||||
|
error = window->priv->error;
|
||||||
|
display = window->priv->display;
|
||||||
|
|
||||||
|
g_mutex_lock (&window->priv->render_lock);
|
||||||
|
|
||||||
|
gl = display->gl_vtable;
|
||||||
|
compiled_api = _compiled_api ();
|
||||||
|
|
||||||
|
user_choice = g_getenv ("GST_GL_API");
|
||||||
|
|
||||||
|
user_api = _parse_gl_api (user_choice);
|
||||||
|
user_api_string = gst_gl_api_string (user_api);
|
||||||
|
|
||||||
|
compiled_api_s = gst_gl_api_string (compiled_api);
|
||||||
|
|
||||||
|
GST_INFO ("Attempting to create opengl context. user chosen api(s):%s, "
|
||||||
|
"compiled api support:%s", user_api_string, compiled_api_s);
|
||||||
|
|
||||||
|
if (!window_class->create_context (window, compiled_api & user_api,
|
||||||
|
window->priv->external_gl_context, error)) {
|
||||||
|
g_assert (error == NULL || *error != NULL);
|
||||||
|
g_free (compiled_api_s);
|
||||||
|
g_free (user_api_string);
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
GST_INFO ("window created context");
|
||||||
|
|
||||||
|
display->gl_api = gst_gl_window_get_gl_api (window);
|
||||||
|
g_assert (display->gl_api != GST_GL_API_NONE
|
||||||
|
&& display->gl_api != GST_GL_API_ANY);
|
||||||
|
|
||||||
|
api_string = gst_gl_api_string (display->gl_api);
|
||||||
|
GST_INFO ("available GL APIs: %s", api_string);
|
||||||
|
|
||||||
|
if (((compiled_api & display->gl_api) & user_api) == GST_GL_API_NONE) {
|
||||||
|
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_WRONG_API,
|
||||||
|
"failed to create context, window "
|
||||||
|
"could not provide correct api. user:%s, compiled:%s, window:%s",
|
||||||
|
user_api_string, compiled_api_s, api_string);
|
||||||
|
g_free (api_string);
|
||||||
|
g_free (compiled_api_s);
|
||||||
|
g_free (user_api_string);
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free (api_string);
|
||||||
|
g_free (compiled_api_s);
|
||||||
|
g_free (user_api_string);
|
||||||
|
|
||||||
|
gl->GetError = gst_gl_window_get_proc_address (window, "glGetError");
|
||||||
|
gl->GetString = gst_gl_window_get_proc_address (window, "glGetString");
|
||||||
|
|
||||||
|
if (!gl->GetError || !gl->GetString) {
|
||||||
|
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_FAILED,
|
||||||
|
"could not GetProcAddress core opengl functions");
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* gl api specific code */
|
||||||
|
if (!ret && USING_OPENGL (display))
|
||||||
|
ret = _create_context_opengl (window, &gl_major, NULL);
|
||||||
|
if (!ret && USING_GLES2 (display))
|
||||||
|
ret = _create_context_gles2 (window, &gl_major, NULL);
|
||||||
|
|
||||||
|
if (!ret || !gl_major) {
|
||||||
|
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_CREATE_CONTEXT,
|
||||||
|
"GL api specific initialization failed");
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_cond_signal (&window->priv->cond_create_context);
|
||||||
|
|
||||||
|
window->priv->alive = TRUE;
|
||||||
|
g_mutex_unlock (&window->priv->render_lock);
|
||||||
|
|
||||||
|
gst_gl_window_run (window);
|
||||||
|
|
||||||
|
GST_INFO ("loop exited\n");
|
||||||
|
|
||||||
|
g_mutex_lock (&window->priv->render_lock);
|
||||||
|
|
||||||
|
window->priv->alive = FALSE;
|
||||||
|
|
||||||
|
// g_object_unref (G_OBJECT (display->gl_window));
|
||||||
|
|
||||||
|
// display->gl_window = NULL;
|
||||||
|
|
||||||
|
g_cond_signal (&window->priv->cond_destroy_context);
|
||||||
|
|
||||||
|
g_mutex_unlock (&window->priv->render_lock);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
failure:
|
||||||
|
{
|
||||||
|
g_cond_signal (&window->priv->cond_create_context);
|
||||||
|
g_mutex_unlock (&window->priv->render_lock);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -22,9 +22,12 @@
|
||||||
#ifndef __GST_GL_WINDOW_H__
|
#ifndef __GST_GL_WINDOW_H__
|
||||||
#define __GST_GL_WINDOW_H__
|
#define __GST_GL_WINDOW_H__
|
||||||
|
|
||||||
|
typedef struct _GstGLDisplay GstGLDisplay;
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
|
|
||||||
#include "gstglapi.h"
|
#include "gstglapi.h"
|
||||||
|
#include "gstgldisplay.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
@ -90,6 +93,8 @@ struct _GstGLWindow {
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
gpointer _reserved[GST_PADDING];
|
gpointer _reserved[GST_PADDING];
|
||||||
|
|
||||||
|
GstGLWindowPrivate *priv;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstGLWindowClass {
|
struct _GstGLWindowClass {
|
||||||
|
@ -119,7 +124,7 @@ struct _GstGLWindowClass {
|
||||||
GQuark gst_gl_window_error_quark (void);
|
GQuark gst_gl_window_error_quark (void);
|
||||||
GType gst_gl_window_get_type (void);
|
GType gst_gl_window_get_type (void);
|
||||||
|
|
||||||
GstGLWindow * gst_gl_window_new (void);
|
GstGLWindow * gst_gl_window_new (GstGLDisplay *display);
|
||||||
|
|
||||||
void gst_gl_window_set_draw_callback (GstGLWindow *window, GstGLWindowCB callback, gpointer data);
|
void gst_gl_window_set_draw_callback (GstGLWindow *window, GstGLWindowCB callback, gpointer data);
|
||||||
void gst_gl_window_set_resize_callback (GstGLWindow *window, GstGLWindowResizeCB callback, gpointer data);
|
void gst_gl_window_set_resize_callback (GstGLWindow *window, GstGLWindowResizeCB callback, gpointer data);
|
||||||
|
@ -140,11 +145,12 @@ gpointer gst_gl_window_get_proc_address (GstGLWindow *window, const gchar *
|
||||||
GstGLPlatform gst_gl_window_get_platform (GstGLWindow *window);
|
GstGLPlatform gst_gl_window_get_platform (GstGLWindow *window);
|
||||||
GstGLAPI gst_gl_window_get_gl_api (GstGLWindow *window);
|
GstGLAPI gst_gl_window_get_gl_api (GstGLWindow *window);
|
||||||
|
|
||||||
gboolean gst_gl_window_create_context (GstGLWindow *window, GstGLAPI gl_api,
|
gboolean gst_gl_window_create_context (GstGLWindow *window, guintptr external_gl_context, GError ** error);
|
||||||
guintptr external_gl_context, GError ** error);
|
|
||||||
|
|
||||||
gpointer gst_gl_window_default_get_proc_address (GstGLWindow *window, const gchar *name);
|
gpointer gst_gl_window_default_get_proc_address (GstGLWindow *window, const gchar *name);
|
||||||
|
|
||||||
|
gboolean gst_gl_window_is_running (GstGLWindow *window);
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_EXTERN (gst_gl_window_debug);
|
GST_DEBUG_CATEGORY_EXTERN (gst_gl_window_debug);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
Loading…
Reference in a new issue