static gboolean gst_gl_context_glx_activate (GstGLContext * context, gboolean activate) { GstGLWindow *window = gst_gl_context_get_window (context); Display *device = (Display *) gst_gl_display_get_handle (window->display); Window window_handle = (Window) gst_gl_window_get_window_handle (window); gboolean result; if (activate) { result = glXMakeCurrent (device, window_handle, GST_GL_CONTEXT_GLX (context)->glx_context); } else { result = glXMakeCurrent (device, None, NULL); } gst_object_unref (window); return result; }
static guintptr gst_gl_context_glx_get_gl_context (GstGLContext * context) { return (guintptr) GST_GL_CONTEXT_GLX (context)->glx_context; }
static gboolean gst_gl_context_glx_choose_format (GstGLContext * context, GError ** error) { GstGLContextGLX *context_glx; GstGLWindow *window; GstGLWindowX11 *window_x11; gint error_base; gint event_base; Display *device; context_glx = GST_GL_CONTEXT_GLX (context); window = gst_gl_context_get_window (context); window_x11 = GST_GL_WINDOW_X11 (window); device = (Display *) gst_gl_display_get_handle (window->display); if (!glXQueryExtension (device, &error_base, &event_base)) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_RESOURCE_UNAVAILABLE, "No GLX extension"); goto failure; } if (!glXQueryVersion (device, &context_glx->priv->glx_major, &context_glx->priv->glx_minor)) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_CREATE_CONTEXT, "Failed to query GLX version (glXQueryVersion failed)"); goto failure; } GST_INFO ("GLX Version: %d.%d", context_glx->priv->glx_major, context_glx->priv->glx_minor); /* legacy case */ if (context_glx->priv->glx_major < 1 || (context_glx->priv->glx_major == 1 && context_glx->priv->glx_minor < 3)) { gint attribs[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, None }; window_x11->visual_info = glXChooseVisual (device, window_x11->screen_num, attribs); if (!window_x11->visual_info) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_CONFIG, "Bad attributes in glXChooseVisual"); goto failure; } } else { gint attribs[] = { GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, True, None }; int fbcount; context_glx->priv->fbconfigs = glXChooseFBConfig (device, DefaultScreen (device), attribs, &fbcount); if (!context_glx->priv->fbconfigs) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_CONFIG, "Could not find any FBConfig's to use (check attributes?)"); goto failure; } _describe_fbconfig (device, context_glx->priv->fbconfigs[0]); window_x11->visual_info = glXGetVisualFromFBConfig (device, context_glx->priv->fbconfigs[0]); if (!window_x11->visual_info) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_CONFIG, "Bad attributes in FBConfig"); goto failure; } } gst_gl_window_x11_create_window ((GstGLWindowX11 *) window); gst_object_unref (window); return TRUE; failure: if (window) gst_object_unref (window); return FALSE; }
static gboolean gst_gl_context_glx_create_context (GstGLContext * context, GstGLAPI gl_api, GstGLContext * other_context, GError ** error) { GstGLContextGLX *context_glx; GstGLWindow *window; GstGLWindowX11 *window_x11; GstGLDisplay *display; gboolean create_context; const char *glx_exts; int x_error; Display *device; guintptr external_gl_context = 0; context_glx = GST_GL_CONTEXT_GLX (context); window = gst_gl_context_get_window (context); window_x11 = GST_GL_WINDOW_X11 (window); display = gst_gl_context_get_display (context); if (other_context) { if (gst_gl_context_get_gl_platform (other_context) != GST_GL_PLATFORM_GLX) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_CONFIG, "Cannot share context with non-GLX context"); goto failure; } external_gl_context = gst_gl_context_get_gl_context (other_context); } device = (Display *) gst_gl_display_get_handle (display); glx_exts = glXQueryExtensionsString (device, DefaultScreen (device)); create_context = gst_gl_check_extension ("GLX_ARB_create_context", glx_exts); context_glx->priv->glXCreateContextAttribsARB = (gpointer) glXGetProcAddressARB ((const GLubyte *) "glXCreateContextAttribsARB"); if (create_context && context_glx->priv->glXCreateContextAttribsARB) { int context_attribs_3[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 0, //GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, #if !defined(GST_DISABLE_GST_DEBUG) GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB, #endif None }; int context_attribs_pre_3[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, 1, GLX_CONTEXT_MINOR_VERSION_ARB, 4, None }; gst_gl_window_x11_trap_x_errors (); context_glx->glx_context = context_glx->priv->glXCreateContextAttribsARB (device, context_glx->priv->fbconfigs[0], (GLXContext) external_gl_context, True, context_attribs_3); x_error = gst_gl_window_x11_untrap_x_errors (); context_glx->priv->context_api = GST_GL_API_OPENGL; if (!context_glx->glx_context || x_error != 0) { GST_DEBUG ("Failed to create an Opengl 3 context. trying a legacy one"); gst_gl_window_x11_trap_x_errors (); context_glx->glx_context = context_glx->priv->glXCreateContextAttribsARB (device, context_glx->priv->fbconfigs[0], (GLXContext) external_gl_context, True, context_attribs_pre_3); x_error = gst_gl_window_x11_untrap_x_errors (); if (x_error != 0) context_glx->glx_context = NULL; context_glx->priv->context_api = GST_GL_API_OPENGL; } } else { context_glx->glx_context = glXCreateContext (device, window_x11->visual_info, (GLXContext) external_gl_context, TRUE); context_glx->priv->context_api = GST_GL_API_OPENGL; } if (context_glx->priv->fbconfigs) XFree (context_glx->priv->fbconfigs); if (!context_glx->glx_context) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_CREATE_CONTEXT, "Failed to create opengl context"); goto failure; } GST_LOG ("gl context id: %ld", (gulong) context_glx->glx_context); gst_object_unref (window); gst_object_unref (display); return TRUE; failure: if (window) gst_object_unref (window); gst_object_unref (display); return FALSE; }
static gboolean gst_gl_context_glx_create_context (GstGLContext * context, GstGLAPI gl_api, GstGLContext * other_context, GError ** error) { GstGLContextGLX *context_glx; GstGLWindow *window; GstGLWindowX11 *window_x11; GstGLDisplay *display = NULL; gboolean create_context; const char *glx_exts; Display *device; guintptr external_gl_context = 0; context_glx = GST_GL_CONTEXT_GLX (context); window = gst_gl_context_get_window (context); if (!GST_IS_GL_WINDOW_X11 (window)) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_CONFIG, "Cannot create an GLX context from a non-X11 window"); goto failure; } window_x11 = GST_GL_WINDOW_X11 (window); display = gst_gl_context_get_display (context); if (other_context) { if (gst_gl_context_get_gl_platform (other_context) != GST_GL_PLATFORM_GLX) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_CONFIG, "Cannot share context with non-GLX context"); goto failure; } external_gl_context = gst_gl_context_get_gl_context (other_context); } device = (Display *) gst_gl_display_get_handle (display); if (!device) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_RESOURCE_UNAVAILABLE, "Invalid Display handle"); goto failure; } glx_exts = glXQueryExtensionsString (device, DefaultScreen (device)); create_context = gst_gl_check_extension ("GLX_ARB_create_context", glx_exts); context_glx->priv->glXCreateContextAttribsARB = (gpointer) glXGetProcAddressARB ((const GLubyte *) "glXCreateContextAttribsARB"); if (!context_glx->glx_context && gl_api & GST_GL_API_OPENGL3 && create_context && context_glx->priv->glXCreateContextAttribsARB) { gint i; for (i = 0; i < G_N_ELEMENTS (opengl_versions); i++) { gint profileMask = 0; gint contextFlags = 0; if ((opengl_versions[i].major > 3 || (opengl_versions[i].major == 3 && opengl_versions[i].minor >= 2))) { profileMask |= GLX_CONTEXT_CORE_PROFILE_BIT_ARB; contextFlags |= GLX_CONTEXT_DEBUG_BIT_ARB; } else { break; } GST_DEBUG_OBJECT (context, "trying to create a GL %d.%d context", opengl_versions[i].major, opengl_versions[i].minor); context_glx->glx_context = _create_context_with_flags (context_glx, device, context_glx->priv->fbconfigs[0], (GLXContext) external_gl_context, opengl_versions[i].major, opengl_versions[i].minor, contextFlags, profileMask); if (context_glx->glx_context) { context_glx->priv->context_api = GST_GL_API_OPENGL3; break; } } } if (!context_glx->glx_context && gl_api & GST_GL_API_OPENGL) { context_glx->glx_context = glXCreateContext (device, window_x11->visual_info, (GLXContext) external_gl_context, TRUE); context_glx->priv->context_api = GST_GL_API_OPENGL; } if (context_glx->priv->fbconfigs) XFree (context_glx->priv->fbconfigs); if (!context_glx->glx_context) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_CREATE_CONTEXT, "Failed to create opengl context"); goto failure; } GST_LOG ("gl context id: %ld", (gulong) context_glx->glx_context); gst_object_unref (window); gst_object_unref (display); return TRUE; failure: if (window) gst_object_unref (window); if (display) gst_object_unref (display); return FALSE; }