summaryrefslogtreecommitdiff
path: root/gst-libs
diff options
context:
space:
mode:
authorMatthew Waters <matthew@centricular.com>2015-08-10 15:44:54 +0200
committerMatthew Waters <matthew@centricular.com>2015-08-10 15:46:13 +0200
commit1a6fe3db40ec3a0946f2870ebb25a9ebed55245f (patch)
treef84c667e8dfc477d2da9515d8df928a8bda6e691 /gst-libs
parent80d77aa0a5975191d845dd84ccc570ee28fd38be (diff)
downloadgstreamer-plugins-bad-1a6fe3db40ec3a0946f2870ebb25a9ebed55245f.tar.gz
glcontext/wgl: implement gl3 core profile context selection
Diffstat (limited to 'gst-libs')
-rw-r--r--gst-libs/gst/gl/utils/opengl_versions.h53
-rw-r--r--gst-libs/gst/gl/win32/gstglcontext_wgl.c138
-rw-r--r--gst-libs/gst/gl/win32/gstglcontext_wgl.h3
-rw-r--r--gst-libs/gst/gl/x11/gstglcontext_glx.c43
4 files changed, 179 insertions, 58 deletions
diff --git a/gst-libs/gst/gl/utils/opengl_versions.h b/gst-libs/gst/gl/utils/opengl_versions.h
new file mode 100644
index 000000000..beeeab641
--- /dev/null
+++ b/gst-libs/gst/gl/utils/opengl_versions.h
@@ -0,0 +1,53 @@
+/*
+ * GStreamer
+ * Copyright (C) 2015 Matthew Waters <matthew@centricular.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _OPENGL_VERSIONS_H_
+#define _OPENGL_VERSIONS_H_
+
+/* list of known OpenGL versions */
+/* *INDENT-OFF* */
+static const struct { int major, minor; } opengl_versions[] = {
+ {4, 5},
+ {4, 4},
+ {4, 3},
+ {4, 2},
+ {4, 1},
+ {4, 0},
+
+ {3, 3},
+ {3, 2},
+ {3, 1},
+ {3, 0},
+
+ {2, 1},
+ {2, 0},
+
+ {1, 5},
+ {1, 4},
+ {1, 3},
+ {1, 2},
+ {1, 1},
+ {1, 0},
+
+ {0, 0} /* end of list */
+};
+/* *INDENT-ON* */
+
+#endif /* _OPENGL_VERSIONS_H_ */
diff --git a/gst-libs/gst/gl/win32/gstglcontext_wgl.c b/gst-libs/gst/gl/win32/gstglcontext_wgl.c
index d950f252b..3c2f34a1a 100644
--- a/gst-libs/gst/gl/win32/gstglcontext_wgl.c
+++ b/gst-libs/gst/gl/win32/gstglcontext_wgl.c
@@ -31,8 +31,19 @@
#include "gstglcontext_wgl.h"
#include <GL/wglext.h>
+#include "../utils/opengl_versions.h"
+
+struct _GstGLContextWGLPrivate
+{
+ PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB;
+
+ GstGLAPI context_api;
+};
+
#define gst_gl_context_wgl_parent_class parent_class
G_DEFINE_TYPE (GstGLContextWGL, gst_gl_context_wgl, GST_GL_TYPE_CONTEXT);
+#define GST_GL_CONTEXT_WGL_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((o), GST_GL_TYPE_CONTEXT_WGL, GstGLContextWGLPrivate))
static guintptr gst_gl_context_wgl_get_gl_context (GstGLContext * context);
static void gst_gl_context_wgl_swap_buffers (GstGLContext * context);
@@ -52,6 +63,8 @@ gst_gl_context_wgl_class_init (GstGLContextWGLClass * klass)
{
GstGLContextClass *context_class = (GstGLContextClass *) klass;
+ g_type_class_add_private (klass, sizeof (GstGLContextWGLPrivate));
+
context_class->get_gl_context =
GST_DEBUG_FUNCPTR (gst_gl_context_wgl_get_gl_context);
context_class->choose_format =
@@ -74,6 +87,9 @@ gst_gl_context_wgl_class_init (GstGLContextWGLClass * klass)
static void
gst_gl_context_wgl_init (GstGLContextWGL * context_wgl)
{
+ context_wgl->priv = GST_GL_CONTEXT_WGL_GET_PRIVATE (context_wgl);
+
+ context_wgl->priv->context_api = GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
}
/* Must be called in the gl thread */
@@ -88,6 +104,44 @@ gst_gl_context_wgl_new (GstGLDisplay * display)
return g_object_new (GST_GL_TYPE_CONTEXT_WGL, NULL);
}
+static HGLRC
+_create_context_with_flags (GstGLContextWGL * context_wgl, HDC dpy,
+ HGLRC share_context, gint major, gint minor, gint contextFlags,
+ gint profileMask)
+{
+ HGLRC ret;
+#define N_ATTRIBS 20
+ gint attribs[N_ATTRIBS];
+ gint n = 0;
+
+ if (major) {
+ attribs[n++] = WGL_CONTEXT_MAJOR_VERSION_ARB;
+ attribs[n++] = major;
+ }
+ if (minor) {
+ attribs[n++] = WGL_CONTEXT_MINOR_VERSION_ARB;
+ attribs[n++] = minor;
+ }
+ if (contextFlags) {
+ attribs[n++] = WGL_CONTEXT_FLAGS_ARB;
+ attribs[n++] = contextFlags;
+ }
+ if (profileMask) {
+ attribs[n++] = WGL_CONTEXT_PROFILE_MASK_ARB;
+ attribs[n++] = profileMask;
+ }
+ attribs[n++] = 0;
+
+ g_assert (n < N_ATTRIBS);
+#undef N_ATTRIBS
+
+ ret =
+ context_wgl->priv->wglCreateContextAttribsARB (dpy, share_context,
+ attribs);
+
+ return ret;
+}
+
static gboolean
gst_gl_context_wgl_create_context (GstGLContext * context,
GstGLAPI gl_api, GstGLContext * other_context, GError ** error)
@@ -95,7 +149,7 @@ gst_gl_context_wgl_create_context (GstGLContext * context,
GstGLWindow *window;
GstGLContextWGL *context_wgl;
HGLRC external_gl_context = NULL;
- PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = NULL;
+ HGLRC trampoline;
HDC device;
context_wgl = GST_GL_CONTEXT_WGL (context);
@@ -112,45 +166,81 @@ gst_gl_context_wgl_create_context (GstGLContext * context,
external_gl_context = (HGLRC) gst_gl_context_get_gl_context (other_context);
}
- context_wgl->wgl_context = wglCreateContext (device);
- if (context_wgl->wgl_context)
+ trampoline = wglCreateContext (device);
+ if (trampoline)
GST_DEBUG ("gl context created: %" G_GUINTPTR_FORMAT,
- (guintptr) context_wgl->wgl_context);
+ (guintptr) trampoline);
else {
g_set_error (error, GST_GL_CONTEXT_ERROR,
GST_GL_CONTEXT_ERROR_CREATE_CONTEXT, "failed to create glcontext:0x%x",
(unsigned int) GetLastError ());
goto failure;
}
- g_assert (context_wgl->wgl_context);
+ g_assert (trampoline);
+
+ /* get extension functions */
+ wglMakeCurrent (device, trampoline);
+
+ context_wgl->priv->wglCreateContextAttribsARB =
+ (PFNWGLCREATECONTEXTATTRIBSARBPROC)
+ wglGetProcAddress ("wglCreateContextAttribsARB");
+
+ wglMakeCurrent (device, 0);
+ wglDeleteContext (trampoline);
+ trampoline = NULL;
+
+ if (context_wgl->priv->wglCreateContextAttribsARB != NULL
+ && gl_api & GST_GL_API_OPENGL3) {
+ 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 |= WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
+ contextFlags |= WGL_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);
- if (external_gl_context) {
+ context_wgl->wgl_context = _create_context_with_flags (context_wgl,
+ device, external_gl_context, opengl_versions[i].major,
+ opengl_versions[i].minor, contextFlags, profileMask);
- wglMakeCurrent (device, context_wgl->wgl_context);
+ if (context_wgl->wgl_context) {
+ context_wgl->priv->context_api = GST_GL_API_OPENGL3;
+ break;
+ }
+ }
+ }
- wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)
- wglGetProcAddress ("wglCreateContextAttribsARB");
+ if (!context_wgl->wgl_context) {
+ context_wgl->wgl_context = wglCreateContext (device);
- if (wglCreateContextAttribsARB != NULL) {
- wglMakeCurrent (device, 0);
- wglDeleteContext (context_wgl->wgl_context);
- context_wgl->wgl_context =
- wglCreateContextAttribsARB (device, external_gl_context, 0);
- if (context_wgl->wgl_context == NULL) {
+ if (!context_wgl->wgl_context) {
+ g_set_error (error, GST_GL_CONTEXT_ERROR,
+ GST_GL_CONTEXT_ERROR_CREATE_CONTEXT,
+ "Failed to create WGL context 0x%x", (unsigned int) GetLastError ());
+ goto failure;
+ }
+
+ if (external_gl_context) {
+ if (!wglShareLists (external_gl_context, context_wgl->wgl_context)) {
g_set_error (error, GST_GL_CONTEXT_ERROR,
GST_GL_CONTEXT_ERROR_CREATE_CONTEXT,
- "failed to share context through wglCreateContextAttribsARB 0x%x",
+ "failed to share contexts through wglShareLists 0x%x",
(unsigned int) GetLastError ());
goto failure;
}
- } else if (!wglShareLists (external_gl_context, context_wgl->wgl_context)) {
- g_set_error (error, GST_GL_CONTEXT_ERROR,
- GST_GL_CONTEXT_ERROR_CREATE_CONTEXT,
- "failed to share contexts through wglShareLists 0x%x",
- (unsigned int) GetLastError ());
- goto failure;
}
+
+ context_wgl->priv->context_api = GST_GL_API_OPENGL;
}
GST_LOG ("gl context id: %" G_GUINTPTR_FORMAT,
@@ -277,7 +367,9 @@ gst_gl_context_wgl_activate (GstGLContext * context, gboolean activate)
GstGLAPI
gst_gl_context_wgl_get_gl_api (GstGLContext * context)
{
- return GST_GL_API_OPENGL;
+ GstGLContextWGL *context_wgl = GST_GL_CONTEXT_WGL (context);
+
+ return context_wgl->priv->context_api;
}
static GstGLPlatform
diff --git a/gst-libs/gst/gl/win32/gstglcontext_wgl.h b/gst-libs/gst/gl/win32/gstglcontext_wgl.h
index 0a3e0670e..64bf14178 100644
--- a/gst-libs/gst/gl/win32/gstglcontext_wgl.h
+++ b/gst-libs/gst/gl/win32/gstglcontext_wgl.h
@@ -34,6 +34,7 @@ G_BEGIN_DECLS
typedef struct _GstGLContextWGL GstGLContextWGL;
typedef struct _GstGLContextWGLClass GstGLContextWGLClass;
+typedef struct _GstGLContextWGLPrivate GstGLContextWGLPrivate;
struct _GstGLContextWGL {
/*< private >*/
@@ -42,6 +43,8 @@ struct _GstGLContextWGL {
HGLRC wgl_context;
HGLRC external_gl_context;
+ GstGLContextWGLPrivate *priv;
+
gpointer _reserved[GST_PADDING];
};
diff --git a/gst-libs/gst/gl/x11/gstglcontext_glx.c b/gst-libs/gst/gl/x11/gstglcontext_glx.c
index e1e9fbbc2..bc83230a8 100644
--- a/gst-libs/gst/gl/x11/gstglcontext_glx.c
+++ b/gst-libs/gst/gl/x11/gstglcontext_glx.c
@@ -36,6 +36,7 @@
#include <gst/gl/gl.h>
#include "gstglcontext_glx.h"
+#include "../utils/opengl_versions.h"
#define GST_CAT_DEFAULT gst_gl_context_debug
@@ -137,35 +138,6 @@ _describe_fbconfig (Display * display, GLXFBConfig config)
GST_DEBUG ("stencil: %d", val);
}
-/* list of known OpenGL versions */
-/* *INDENT-OFF* */
-static const struct { int major, minor; } gl_versions[] = {
- {4, 5},
- {4, 4},
- {4, 3},
- {4, 2},
- {4, 1},
- {4, 0},
-
- {3, 3},
- {3, 2},
- {3, 1},
- {3, 0},
-
- {2, 1},
- {2, 0},
-
- {1, 5},
- {1, 4},
- {1, 3},
- {1, 2},
- {1, 1},
- {1, 0},
-
- {0, 0} /* end of list */
-};
-/* *INDENT-ON* */
-
static GLXContext
_create_context_with_flags (GstGLContextGLX * context_glx, Display * dpy,
GLXFBConfig fbconfig, GLXContext share_context, gint major, gint minor,
@@ -252,12 +224,13 @@ gst_gl_context_glx_create_context (GstGLContext * context,
&& context_glx->priv->glXCreateContextAttribsARB) {
gint i;
- for (i = 0; i < G_N_ELEMENTS (gl_versions); i++) {
+ for (i = 0; i < G_N_ELEMENTS (opengl_versions); i++) {
gint profileMask = 0;
gint contextFlags = 0;
- if ((gl_versions[i].major > 3
- || (gl_versions[i].major == 3 && gl_versions[i].minor >= 2))) {
+ 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 {
@@ -265,12 +238,12 @@ gst_gl_context_glx_create_context (GstGLContext * context,
}
GST_DEBUG_OBJECT (context, "trying to create a GL %d.%d context",
- gl_versions[i].major, gl_versions[i].minor);
+ 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, gl_versions[i].major,
- gl_versions[i].minor, contextFlags, profileMask);
+ (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;