mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
[794/906] context: add subclasses for the different platforms (egl, glx, wgl, etc)
- most code taken from the Window subclasses - tested combinations: xEGL, GLX, Wayland+EGL, Cocoa (under GNUStep), WGL (Wine)
This commit is contained in:
parent
e80533dcee
commit
9cbb652b66
29 changed files with 1657 additions and 1721 deletions
|
@ -3,10 +3,13 @@
|
|||
noinst_LTLIBRARIES = libgstgl-cocoa.la
|
||||
|
||||
libgstgl_cocoa_la_SOURCES = \
|
||||
gstglwindow_cocoa.m
|
||||
gstglwindow_cocoa.m \
|
||||
gstglcontext_cocoa.m
|
||||
|
||||
noinst_HEADERS = \
|
||||
gstglwindow_cocoa.h
|
||||
gstglwindow_cocoa.h \
|
||||
gstglcontext_cocoa.h \
|
||||
gstgl_cocoa_private.h
|
||||
|
||||
libgstgl_cocoa_la_CFLAGS = \
|
||||
-I$(top_srcdir)/gst-libs \
|
||||
|
|
78
gst-libs/gst/gl/cocoa/gstgl_cocoa_private.h
Normal file
78
gst-libs/gst/gl/cocoa/gstgl_cocoa_private.h
Normal file
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* GStreamer
|
||||
* Copyright (C) 2012 Matthew Waters <ystreet00@gmail.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 __GST_GL_COCOA_PRIVATE_H__
|
||||
#define __GST_GL_COCOA_PRIVATE_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include <Cocoa/Cocoa.h>
|
||||
|
||||
#include "gstglwindow_cocoa.h"
|
||||
#include "gstglcontext_cocoa.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@interface AppThreadPerformer : NSObject {
|
||||
GstGLWindowCocoa *m_cocoa;
|
||||
GstGLWindowCB m_callback;
|
||||
GstGLWindowResizeCB m_callback2;
|
||||
gpointer m_data;
|
||||
gint m_width;
|
||||
gint m_height;
|
||||
}
|
||||
- (id) init: (GstGLWindowCocoa *)window;
|
||||
- (id) initWithCallback:(GstGLWindowCocoa *)window callback:(GstGLWindowCB)callback userData:(gpointer) data;
|
||||
- (id) initWithSize: (GstGLWindowCocoa *)window callback:(GstGLWindowResizeCB)callback userData:(gpointer)data toSize:(NSSize)size;
|
||||
- (id) initWithAll: (GstGLWindowCocoa *)window callback:(GstGLWindowCB)callback userData:(gpointer) data;
|
||||
- (void) updateWindow;
|
||||
- (void) sendToApp;
|
||||
- (void) setWindow;
|
||||
- (void) stopApp;
|
||||
- (void) closeWindow;
|
||||
@end
|
||||
|
||||
struct _GstGLContextCocoaPrivate
|
||||
{
|
||||
NSOpenGLContext *gl_context;
|
||||
NSOpenGLContext *external_gl_context;
|
||||
NSRect rect;
|
||||
};
|
||||
|
||||
|
||||
/* =============================================================*/
|
||||
/* */
|
||||
/* GstGLNSOpenGLView declaration */
|
||||
/* */
|
||||
/* =============================================================*/
|
||||
|
||||
@interface GstGLNSOpenGLView: NSOpenGLView {
|
||||
GstGLWindowCocoa *m_cocoa;
|
||||
gint m_resizeCount;
|
||||
}
|
||||
- (id) initWithFrame:(GstGLWindowCocoa *)window rect:(NSRect)contentRect
|
||||
pixelFormat:(NSOpenGLPixelFormat *)fmt;
|
||||
@end
|
||||
|
||||
gboolean gst_gl_window_cocoa_create_window (GstGLWindowCocoa *window_cocoa);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_GL_COCOA_PRIVATE_H__ */
|
67
gst-libs/gst/gl/cocoa/gstglcontext_cocoa.h
Normal file
67
gst-libs/gst/gl/cocoa/gstglcontext_cocoa.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* GStreamer
|
||||
* Copyright (C) 2012 Matthew Waters <ystreet00@gmail.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 __GST_GL_CONTEXT_COCOA_H__
|
||||
#define __GST_GL_CONTEXT_COCOA_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include <gst/gl/gl.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_GL_TYPE_CONTEXT_COCOA (gst_gl_context_cocoa_get_type())
|
||||
#define GST_GL_CONTEXT_COCOA(o) (G_TYPE_CHECK_INSTANCE_CAST((o), GST_GL_TYPE_CONTEXT_COCOA, GstGLContextCocoa))
|
||||
#define GST_GL_CONTEXT_COCOA_CLASS(k) (G_TYPE_CHECK_CLASS((k), GST_GL_TYPE_CONTEXT_COCOA, GstGLContextCocoaClass))
|
||||
#define GST_GL_IS_CONTEXT_COCOA(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), GST_GL_TYPE_CONTEXT_COCOA))
|
||||
#define GST_GL_IS_CONTEXT_COCOA_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), GST_GL_TYPE_CONTEXT_COCOA))
|
||||
#define GST_GL_CONTEXT_COCOA_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_GL_TYPE_CONTEXT_COCOA, GstGLContextCocoaClass))
|
||||
|
||||
typedef struct _GstGLContextCocoa GstGLContextCocoa;
|
||||
typedef struct _GstGLContextCocoaPrivate GstGLContextCocoaPrivate;
|
||||
typedef struct _GstGLContextCocoaClass GstGLContextCocoaClass;
|
||||
|
||||
struct _GstGLContextCocoa {
|
||||
/*< private >*/
|
||||
GstGLContext parent;
|
||||
|
||||
/*< private >*/
|
||||
GstGLContextCocoaPrivate *priv;
|
||||
|
||||
gpointer _reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
struct _GstGLContextCocoaClass {
|
||||
/*< private >*/
|
||||
GstGLContextClass parent_class;
|
||||
|
||||
/*< private >*/
|
||||
gpointer _reserved[GST_PADDING_LARGE];
|
||||
|
||||
GstGLContextCocoaPrivate *priv;
|
||||
};
|
||||
|
||||
GType gst_gl_context_cocoa_get_type (void);
|
||||
|
||||
GstGLContextCocoa * gst_gl_context_cocoa_new (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_GL_CONTEXT_COCOA_H__ */
|
218
gst-libs/gst/gl/cocoa/gstglcontext_cocoa.m
Normal file
218
gst-libs/gst/gl/cocoa/gstglcontext_cocoa.m
Normal file
|
@ -0,0 +1,218 @@
|
|||
/*
|
||||
* GStreamer
|
||||
* Copyright (C) 2012 Matthew Waters <ystreet00@gmail.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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <Cocoa/Cocoa.h>
|
||||
|
||||
#include "gstglcontext_cocoa.h"
|
||||
#include "gstgl_cocoa_private.h"
|
||||
|
||||
static gboolean gst_gl_context_cocoa_create_context (GstGLContext *context, GstGLAPI gl_api,
|
||||
guintptr external_opengl_context, GError **error);
|
||||
static guintptr gst_gl_context_cocoa_get_gl_context (GstGLContext * window);
|
||||
static gboolean gst_gl_context_cocoa_activate (GstGLContext * context, gboolean activate);
|
||||
static GstGLAPI gst_gl_context_cocoa_get_gl_api (GstGLContext * context);
|
||||
|
||||
#define GST_GL_CONTEXT_COCOA_GET_PRIVATE(o) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE((o), GST_GL_TYPE_CONTEXT_COCOA, GstGLContextCocoaPrivate))
|
||||
|
||||
G_DEFINE_TYPE (GstGLContextCocoa, gst_gl_context_cocoa, GST_GL_TYPE_CONTEXT);
|
||||
|
||||
static void
|
||||
gst_gl_context_cocoa_class_init (GstGLContextCocoaClass * klass)
|
||||
{
|
||||
GstGLContextClass *context_class;
|
||||
|
||||
#ifndef GNUSTEP
|
||||
NSAutoreleasePool* pool = nil;
|
||||
#endif
|
||||
|
||||
context_class = (GstGLContextClass *) klass;
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GstGLContextCocoaPrivate));
|
||||
|
||||
context_class->create_context =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_context_cocoa_create_context);
|
||||
context_class->get_gl_context =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_context_cocoa_get_gl_context);
|
||||
context_class->activate = GST_DEBUG_FUNCPTR (gst_gl_context_cocoa_activate);
|
||||
context_class->get_gl_api =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_context_cocoa_get_gl_api);
|
||||
|
||||
#ifndef GNUSTEP
|
||||
pool = [[NSAutoreleasePool alloc] init];
|
||||
[NSApplication sharedApplication];
|
||||
|
||||
[pool release];
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_context_cocoa_init (GstGLContextCocoa * context)
|
||||
{
|
||||
context->priv = GST_GL_CONTEXT_COCOA_GET_PRIVATE (context);
|
||||
}
|
||||
|
||||
/* Must be called in the gl thread */
|
||||
GstGLContextCocoa *
|
||||
gst_gl_context_cocoa_new (void)
|
||||
{
|
||||
GstGLContextCocoa *context = g_object_new (GST_GL_TYPE_CONTEXT_COCOA, NULL);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_gl_context_cocoa_create_context (GstGLContext *context, GstGLAPI gl_api,
|
||||
guintptr external_gl_context, GError **error)
|
||||
{
|
||||
GstGLContextCocoa *context_cocoa = GST_GL_CONTEXT_COCOA (context);
|
||||
GstGLContextCocoaPrivate *priv = context_cocoa->priv;
|
||||
GstGLWindow *window = gst_gl_context_get_window (context);
|
||||
GstGLWindowCocoa *window_cocoa = GST_GL_WINDOW_COCOA (window);
|
||||
GstGLNSOpenGLView *glView = nil;
|
||||
NSWindow *window_handle;
|
||||
NSRect rect;
|
||||
NSAutoreleasePool *pool;
|
||||
NSOpenGLPixelFormat *fmt = nil;
|
||||
NSOpenGLContext *glContext = nil;
|
||||
NSOpenGLPixelFormatAttribute attribs[] = {
|
||||
NSOpenGLPFADoubleBuffer,
|
||||
NSOpenGLPFAAccumSize, 32,
|
||||
0
|
||||
};
|
||||
|
||||
priv->gl_context = nil;
|
||||
priv->external_gl_context = (NSOpenGLContext *) external_gl_context;
|
||||
|
||||
GSRegisterCurrentThread();
|
||||
|
||||
pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
#ifdef GNUSTEP
|
||||
[NSApplication sharedApplication];
|
||||
#endif
|
||||
|
||||
rect.origin.x = 0;
|
||||
rect.origin.y = 0;
|
||||
rect.size.width = 320;
|
||||
rect.size.height = 240;
|
||||
|
||||
priv->rect = rect;
|
||||
|
||||
gst_gl_window_cocoa_create_window (window_cocoa);
|
||||
window_handle = (NSWindow *) gst_gl_window_get_window_handle (window);
|
||||
|
||||
glView = [GstGLNSOpenGLView alloc];
|
||||
|
||||
fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
|
||||
|
||||
if (!fmt) {
|
||||
gst_object_unref (window);
|
||||
GST_WARNING ("cannot create NSOpenGLPixelFormat");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
glView = [glView initWithFrame:window_cocoa rect:rect pixelFormat:fmt];
|
||||
|
||||
[window_handle setContentView:glView];
|
||||
|
||||
#ifndef GNUSTEP
|
||||
glContext = [[NSOpenGLContext alloc] initWithFormat:fmt
|
||||
shareContext:context_cocoa->priv->external_gl_context];
|
||||
|
||||
GST_DEBUG ("NSOpenGL context created: %lud\n", (guintptr) glContext);
|
||||
|
||||
context_cocoa->priv->gl_context = glContext;
|
||||
|
||||
[glView setOpenGLContext:glContext];
|
||||
#else
|
||||
context_cocoa->priv->gl_context = [glView openGLContext];
|
||||
#endif
|
||||
|
||||
/* OpenGL context is made current only one time threre.
|
||||
* Indeed, all OpenGL calls are made in only one thread,
|
||||
* the Application thread */
|
||||
[glContext makeCurrentContext];
|
||||
|
||||
[glContext update];
|
||||
|
||||
/* Back and front buffers are swapped only during the vertical retrace of the monitor.
|
||||
* Discarded if you configured your driver to Never-use-V-Sync.
|
||||
*/
|
||||
NS_DURING {
|
||||
if (glContext) {
|
||||
#ifdef GNUSTEP
|
||||
const long swapInterval = 1;
|
||||
#else
|
||||
const GLint swapInterval = 1;
|
||||
#endif
|
||||
[[glView openGLContext] setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval];
|
||||
}
|
||||
} NS_HANDLER {
|
||||
GST_DEBUG ("your back-end does not implement NSOpenglContext::setValues\n");
|
||||
}
|
||||
NS_ENDHANDLER
|
||||
|
||||
GST_DEBUG ("opengl GstGLNSWindow initialized: %d x %d\n",
|
||||
(gint) rect.size.width, (gint) rect.size.height);
|
||||
|
||||
[pool release];
|
||||
|
||||
#ifndef GNUSTEP
|
||||
priv->source_id = g_timeout_add_seconds (1, gst_gl_window_cocoa_nsapp_iteration, NULL);
|
||||
#endif
|
||||
|
||||
gst_object_unref (window);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static guintptr
|
||||
gst_gl_context_cocoa_get_gl_context (GstGLContext * context)
|
||||
{
|
||||
return (guintptr) GST_GL_CONTEXT_COCOA (context)->priv->gl_context;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_gl_context_cocoa_activate (GstGLContext * context, gboolean activate)
|
||||
{
|
||||
GstGLContextCocoa *context_cocoa;
|
||||
|
||||
context_cocoa = GST_GL_CONTEXT_COCOA (context);
|
||||
|
||||
if (activate)
|
||||
[context_cocoa->priv->gl_context makeCurrentContext];
|
||||
#if 0
|
||||
else
|
||||
/* FIXME */
|
||||
[context_cocoa->priv->gl_context clearCurrentContext];
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstGLAPI
|
||||
gst_gl_context_cocoa_get_gl_api (GstGLContext * context)
|
||||
{
|
||||
return GST_GL_API_OPENGL;
|
||||
}
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
#include <Cocoa/Cocoa.h>
|
||||
|
||||
#include "gstglwindow_cocoa.h"
|
||||
#include "gstgl_cocoa_private.h"
|
||||
|
||||
/* =============================================================*/
|
||||
/* */
|
||||
|
@ -47,47 +47,6 @@
|
|||
- (BOOL) canBecomeKeyWindow;
|
||||
@end
|
||||
|
||||
/* =============================================================*/
|
||||
/* */
|
||||
/* GstGLNSOpenGLView declaration */
|
||||
/* */
|
||||
/* =============================================================*/
|
||||
|
||||
@interface GstGLNSOpenGLView: NSOpenGLView {
|
||||
GstGLWindowCocoa *m_cocoa;
|
||||
gint m_resizeCount;
|
||||
}
|
||||
- (id) initWithFrame:(GstGLWindowCocoa *)window rect:(NSRect)contentRect
|
||||
pixelFormat:(NSOpenGLPixelFormat *)fmt;
|
||||
@end
|
||||
|
||||
|
||||
/* =============================================================*/
|
||||
/* */
|
||||
/* AppThreadPerformer declaration */
|
||||
/* */
|
||||
/* =============================================================*/
|
||||
|
||||
/* Perform actions in the Application thread */
|
||||
@interface AppThreadPerformer : NSObject {
|
||||
GstGLWindowCocoa *m_cocoa;
|
||||
GstGLWindowCB m_callback;
|
||||
GstGLWindowResizeCB m_callback2;
|
||||
gpointer m_data;
|
||||
gint m_width;
|
||||
gint m_height;
|
||||
}
|
||||
- (id) init: (GstGLWindowCocoa *)window;
|
||||
- (id) initWithCallback:(GstGLWindowCocoa *)window callback:(GstGLWindowCB)callback userData:(gpointer) data;
|
||||
- (id) initWithSize: (GstGLWindowCocoa *)window callback:(GstGLWindowResizeCB)callback userData:(gpointer)data toSize:(NSSize)size;
|
||||
- (id) initWithAll: (GstGLWindowCocoa *)window callback:(GstGLWindowCB)callback userData:(gpointer) data;
|
||||
- (void) updateWindow;
|
||||
- (void) sendToApp;
|
||||
- (void) setWindow;
|
||||
- (void) stopApp;
|
||||
- (void) closeWindow;
|
||||
@end
|
||||
|
||||
/* =============================================================*/
|
||||
/* */
|
||||
/* GstGLWindow */
|
||||
|
@ -110,26 +69,18 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
|||
#define gst_gl_window_cocoa_parent_class parent_class
|
||||
G_DEFINE_TYPE_WITH_CODE (GstGLWindowCocoa, gst_gl_window_cocoa, GST_GL_TYPE_WINDOW, DEBUG_INIT);
|
||||
|
||||
gboolean gst_gl_window_cocoa_create_context (GstGLWindow *window, GstGLAPI gl_api,
|
||||
guintptr external_opengl_context, GError **error);
|
||||
guintptr gst_gl_window_cocoa_get_gl_context (GstGLWindow * window);
|
||||
gboolean gst_gl_window_cocoa_activate (GstGLWindow * window, gboolean activate);
|
||||
void gst_gl_window_cocoa_set_window_handle (GstGLWindow * window,
|
||||
static guintptr gst_gl_window_cocoa_get_window_handle (GstGLWindow * window);
|
||||
static void gst_gl_window_cocoa_set_window_handle (GstGLWindow * window,
|
||||
guintptr handle);
|
||||
void gst_gl_window_cocoa_draw_unlocked (GstGLWindow * window, guint width,
|
||||
guint height);
|
||||
void gst_gl_window_cocoa_draw (GstGLWindow * window, guint width, guint height);
|
||||
void gst_gl_window_cocoa_run (GstGLWindow * window);
|
||||
void gst_gl_window_cocoa_quit (GstGLWindow * window);
|
||||
void gst_gl_window_cocoa_send_message (GstGLWindow * window,
|
||||
static void gst_gl_window_cocoa_draw (GstGLWindow * window, guint width, guint height);
|
||||
static void gst_gl_window_cocoa_run (GstGLWindow * window);
|
||||
static void gst_gl_window_cocoa_quit (GstGLWindow * window);
|
||||
static void gst_gl_window_cocoa_send_message (GstGLWindow * window,
|
||||
GstGLWindowCB callback, gpointer data);
|
||||
GstGLAPI gst_gl_window_cocoa_get_gl_api (GstGLWindow * window);
|
||||
|
||||
struct _GstGLWindowCocoaPrivate
|
||||
{
|
||||
GstGLNSWindow *internal_win_id;
|
||||
NSOpenGLContext *gl_context;
|
||||
NSOpenGLContext *external_gl_context;
|
||||
gboolean visible;
|
||||
NSWindow *parent;
|
||||
NSThread *thread;
|
||||
|
@ -148,9 +99,10 @@ gst_gl_window_cocoa_nsapp_iteration (gpointer data)
|
|||
|
||||
while ((event = ([NSApp nextEventMatchingMask:NSAnyEventMask
|
||||
untilDate:[NSDate dateWithTimeIntervalSinceNow:0.5]
|
||||
inMode:NSDefaultRunLoopMode dequeue:YES])) != nil)
|
||||
inMode:NSDefaultRunLoopMode dequeue:YES])) != nil) {
|
||||
|
||||
[NSApp sendEvent:event];
|
||||
}
|
||||
}
|
||||
|
||||
[pool release];
|
||||
|
@ -171,11 +123,8 @@ gst_gl_window_cocoa_class_init (GstGLWindowCocoaClass * klass)
|
|||
|
||||
g_type_class_add_private (klass, sizeof (GstGLWindowCocoaPrivate));
|
||||
|
||||
window_class->create_context =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_create_context);
|
||||
window_class->get_gl_context =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_get_gl_context);
|
||||
window_class->activate = GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_activate);
|
||||
window_class->get_window_handle =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_get_window_handle);
|
||||
window_class->set_window_handle =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_set_window_handle);
|
||||
window_class->draw_unlocked = GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_draw);
|
||||
|
@ -184,8 +133,6 @@ gst_gl_window_cocoa_class_init (GstGLWindowCocoaClass * klass)
|
|||
window_class->quit = GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_quit);
|
||||
window_class->send_message =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_send_message);
|
||||
window_class->get_gl_api =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_get_gl_api);
|
||||
|
||||
#ifndef GNUSTEP
|
||||
pool = [[NSAutoreleasePool alloc] init];
|
||||
|
@ -213,33 +160,13 @@ gst_gl_window_cocoa_new (void)
|
|||
}
|
||||
|
||||
gboolean
|
||||
gst_gl_window_cocoa_create_context (GstGLWindow *window, GstGLAPI gl_api,
|
||||
guintptr external_gl_context, GError **error)
|
||||
gst_gl_window_cocoa_create_window (GstGLWindowCocoa *window_cocoa)
|
||||
{
|
||||
GstGLWindowCocoa *window_cocoa = GST_GL_WINDOW_COCOA (window);
|
||||
GstGLWindow *window = GST_GL_WINDOW (window_cocoa);
|
||||
GstGLContext *context = gst_gl_window_get_context (window);
|
||||
GstGLContextCocoa *context_cocoa = GST_GL_CONTEXT_COCOA (context);
|
||||
GstGLWindowCocoaPrivate *priv = window_cocoa->priv;
|
||||
NSRect rect;
|
||||
NSAutoreleasePool *pool;
|
||||
|
||||
priv->internal_win_id = nil;
|
||||
priv->gl_context = nil;
|
||||
priv->external_gl_context = (NSOpenGLContext *) external_gl_context;
|
||||
priv->visible = FALSE;
|
||||
priv->thread = nil;
|
||||
priv->running = TRUE;
|
||||
|
||||
GSRegisterCurrentThread();
|
||||
|
||||
pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
#ifdef GNUSTEP
|
||||
[NSApplication sharedApplication];
|
||||
#endif
|
||||
|
||||
rect.origin.x = 0;
|
||||
rect.origin.y = 0;
|
||||
rect.size.width = 320;
|
||||
rect.size.height = 240;
|
||||
NSRect rect = context_cocoa->priv->rect;
|
||||
|
||||
priv->internal_win_id =[[GstGLNSWindow alloc] initWithContentRect:rect styleMask:
|
||||
(NSTitledWindowMask | NSClosableWindowMask |
|
||||
|
@ -247,46 +174,23 @@ gst_gl_window_cocoa_create_context (GstGLWindow *window, GstGLAPI gl_api,
|
|||
backing: NSBackingStoreBuffered defer: NO screen: nil gstWin: window_cocoa];
|
||||
|
||||
GST_DEBUG ("NSWindow id: %lud\n", (guintptr) priv->internal_win_id);
|
||||
|
||||
|
||||
priv->thread = [NSThread currentThread];
|
||||
|
||||
[NSApp setDelegate: priv->internal_win_id];
|
||||
|
||||
[pool release];
|
||||
|
||||
#ifndef GNUSTEP
|
||||
priv->source_id = g_timeout_add_seconds (1, gst_gl_window_cocoa_nsapp_iteration, NULL);
|
||||
#endif
|
||||
gst_object_unref (context);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
guintptr
|
||||
gst_gl_window_cocoa_get_gl_context (GstGLWindow * window)
|
||||
static guintptr
|
||||
gst_gl_window_cocoa_get_window_handle (GstGLWindow *window)
|
||||
{
|
||||
return (guintptr) GST_GL_WINDOW_COCOA (window)->priv->gl_context;
|
||||
return (guintptr) GST_GL_WINDOW_COCOA (window)->priv->internal_win_id;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_gl_window_cocoa_activate (GstGLWindow * window, gboolean activate)
|
||||
{
|
||||
GstGLWindowCocoa *window_cocoa;
|
||||
GstGLWindowCocoaPrivate *priv;
|
||||
|
||||
window_cocoa = GST_GL_WINDOW_COCOA (window);
|
||||
priv = window_cocoa->priv;
|
||||
|
||||
if (activate)
|
||||
[priv->gl_context makeCurrentContext];
|
||||
#if 0
|
||||
else
|
||||
/* FIXME */
|
||||
[priv->gl_context clearCurrentContext];
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
gst_gl_window_cocoa_set_window_handle (GstGLWindow * window, guintptr handle)
|
||||
{
|
||||
GstGLWindowCocoa *window_cocoa;
|
||||
|
@ -316,7 +220,7 @@ gst_gl_window_cocoa_set_window_handle (GstGLWindow * window, guintptr handle)
|
|||
}
|
||||
|
||||
/* Thread safe */
|
||||
void
|
||||
static void
|
||||
gst_gl_window_cocoa_draw (GstGLWindow * window, guint width, guint height)
|
||||
{
|
||||
GstGLWindowCocoa *window_cocoa;
|
||||
|
@ -373,7 +277,7 @@ gst_gl_window_cocoa_draw (GstGLWindow * window, guint width, guint height)
|
|||
GST_DEBUG ("failed to register current thread, cannot draw\n");
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
gst_gl_window_cocoa_run (GstGLWindow * window)
|
||||
{
|
||||
GstGLWindowCocoa *window_cocoa;
|
||||
|
@ -389,6 +293,7 @@ gst_gl_window_cocoa_run (GstGLWindow * window)
|
|||
GST_DEBUG ("begin loop\n");
|
||||
|
||||
if (priv->internal_win_id != nil) {
|
||||
priv->running = TRUE;
|
||||
#ifndef GNUSTEP
|
||||
while (priv->running)
|
||||
[run_loop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
|
||||
|
@ -406,7 +311,7 @@ gst_gl_window_cocoa_run (GstGLWindow * window)
|
|||
}
|
||||
|
||||
/* Thread safe */
|
||||
void
|
||||
static void
|
||||
gst_gl_window_cocoa_quit (GstGLWindow * window)
|
||||
{
|
||||
GstGLWindowCocoa *window_cocoa;
|
||||
|
@ -419,8 +324,10 @@ gst_gl_window_cocoa_quit (GstGLWindow * window)
|
|||
if (GSRegisterCurrentThread() || 1) {
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
AppThreadPerformer* app_thread_performer = [[AppThreadPerformer alloc] initWithAll:window_cocoa callback:NULL userData:NULL];
|
||||
[app_thread_performer performSelector:@selector(stopApp) onThread:priv->thread withObject:nil waitUntilDone:YES];
|
||||
AppThreadPerformer* app_thread_performer = [[AppThreadPerformer alloc]
|
||||
initWithAll:window_cocoa callback:NULL userData:NULL];
|
||||
[app_thread_performer performSelector:@selector(stopApp)
|
||||
onThread:priv->thread withObject:nil waitUntilDone:YES];
|
||||
|
||||
[pool release];
|
||||
|
||||
|
@ -432,7 +339,7 @@ gst_gl_window_cocoa_quit (GstGLWindow * window)
|
|||
}
|
||||
|
||||
/* Thread safe */
|
||||
void
|
||||
static void
|
||||
gst_gl_window_cocoa_send_message (GstGLWindow * window, GstGLWindowCB callback,
|
||||
gpointer data)
|
||||
{
|
||||
|
@ -461,12 +368,6 @@ gst_gl_window_cocoa_send_message (GstGLWindow * window, GstGLWindowCB callback,
|
|||
}
|
||||
}
|
||||
|
||||
GstGLAPI
|
||||
gst_gl_window_cocoa_get_gl_api (GstGLWindow * window)
|
||||
{
|
||||
return GST_GL_API_OPENGL;
|
||||
}
|
||||
|
||||
/* =============================================================*/
|
||||
/* */
|
||||
/* GstGLNSWindow implementation */
|
||||
|
@ -481,15 +382,6 @@ gst_gl_window_cocoa_get_gl_api (GstGLWindow * window)
|
|||
defer: (BOOL) flag screen: (NSScreen *) aScreen
|
||||
gstWin: (GstGLWindowCocoa *) cocoa {
|
||||
|
||||
GstGLNSOpenGLView *glView = nil;
|
||||
NSOpenGLPixelFormat *fmt = nil;
|
||||
NSOpenGLContext *glContext = nil;
|
||||
NSOpenGLPixelFormatAttribute attribs[] = {
|
||||
NSOpenGLPFADoubleBuffer,
|
||||
NSOpenGLPFAAccumSize, 32,
|
||||
0
|
||||
};
|
||||
|
||||
m_isClosed = NO;
|
||||
m_cocoa = cocoa;
|
||||
|
||||
|
@ -501,66 +393,12 @@ gst_gl_window_cocoa_get_gl_api (GstGLWindow * window)
|
|||
|
||||
GST_DEBUG ("initializing GstGLNSWindow\n");
|
||||
|
||||
glView = [GstGLNSOpenGLView alloc];
|
||||
|
||||
fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
|
||||
|
||||
if (!fmt) {
|
||||
GST_WARNING ("cannot create NSOpenGLPixelFormat");
|
||||
return nil;
|
||||
}
|
||||
|
||||
glView = [glView initWithFrame:m_cocoa rect:contentRect pixelFormat:fmt];
|
||||
|
||||
[self setContentView:glView];
|
||||
|
||||
#ifndef GNUSTEP
|
||||
glContext = [[NSOpenGLContext alloc] initWithFormat:fmt
|
||||
shareContext:m_cocoa->priv->external_gl_context];
|
||||
|
||||
GST_DEBUG ("NSOpenGL context created: %lud\n", (guintptr) glContext);
|
||||
|
||||
m_cocoa->priv->gl_context = glContext;
|
||||
|
||||
[glView setOpenGLContext:glContext];
|
||||
#else
|
||||
glContext = [glView openGLContext];
|
||||
#endif
|
||||
|
||||
/* OpenGL context is made current only one time threre.
|
||||
* Indeed, all OpenGL calls are made in only one thread,
|
||||
* the Application thread */
|
||||
[glContext makeCurrentContext];
|
||||
|
||||
[glContext update];
|
||||
|
||||
/* Back and front buffers are swapped only during the vertical retrace of the monitor.
|
||||
* Discarded if you configured your driver to Never-use-V-Sync.
|
||||
*/
|
||||
NS_DURING {
|
||||
if (glContext) {
|
||||
#ifdef GNUSTEP
|
||||
const long swapInterval = 1;
|
||||
#else
|
||||
const GLint swapInterval = 1;
|
||||
#endif
|
||||
[[glView openGLContext] setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval];
|
||||
}
|
||||
} NS_HANDLER {
|
||||
GST_DEBUG ("your back-end does not implement NSOpenglContext::setValues\n");
|
||||
}
|
||||
NS_ENDHANDLER
|
||||
|
||||
GST_DEBUG ("opengl GstGLNSWindow initialized: %d x %d\n",
|
||||
(gint) contentRect.size.width, (gint) contentRect.size.height);
|
||||
|
||||
[self setTitle:@"OpenGL renderer"];
|
||||
|
||||
[self setBackgroundColor:[NSColor clearColor]];
|
||||
|
||||
[self orderOut:m_cocoa->priv->internal_win_id];
|
||||
|
||||
|
||||
if (m_cocoa->priv->parent) {
|
||||
NSWindow *window = m_cocoa->priv->parent;
|
||||
[window setContentView: [m_cocoa->priv->internal_win_id contentView]];
|
||||
|
@ -639,17 +477,17 @@ gst_gl_window_cocoa_get_gl_api (GstGLWindow * window)
|
|||
@implementation GstGLNSOpenGLView
|
||||
|
||||
- (id)initWithFrame:(GstGLWindowCocoa *)window rect:(NSRect)contentRect pixelFormat:(NSOpenGLPixelFormat *)fmt {
|
||||
|
||||
|
||||
self = [super initWithFrame: contentRect pixelFormat: fmt];
|
||||
|
||||
|
||||
m_cocoa = window;
|
||||
m_resizeCount = 0;
|
||||
|
||||
|
||||
#ifndef GNUSTEP
|
||||
[self setWantsLayer:NO];
|
||||
#endif
|
||||
|
||||
return self;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)reshape {
|
||||
|
@ -660,7 +498,7 @@ gst_gl_window_cocoa_get_gl_api (GstGLWindow * window)
|
|||
if (m_resizeCount % 5 == 0) {
|
||||
m_resizeCount = 0;
|
||||
if (window->resize) {
|
||||
|
||||
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
NSRect bounds = [self bounds];
|
||||
AppThreadPerformer* app_thread_performer = [[AppThreadPerformer alloc]
|
||||
|
|
|
@ -27,6 +27,19 @@
|
|||
#include "gl.h"
|
||||
#include "gstglcontext.h"
|
||||
|
||||
#if GST_GL_HAVE_PLATFORM_GLX
|
||||
#include "x11/gstglcontext_glx.h"
|
||||
#endif
|
||||
#if GST_GL_HAVE_PLATFORM_EGL
|
||||
#include "gstglegl.h"
|
||||
#endif
|
||||
#if GST_GL_HAVE_PLATFORM_COCOA
|
||||
#include "cocoa/gstglcontext_cocoa.h"
|
||||
#endif
|
||||
#if GST_GL_HAVE_PLATFORM_WGL
|
||||
#include "win32/gstglcontext_wgl.h"
|
||||
#endif
|
||||
|
||||
#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)
|
||||
|
@ -37,7 +50,7 @@
|
|||
GST_DEBUG_CATEGORY (GST_CAT_DEFAULT);
|
||||
|
||||
#define gst_gl_context_parent_class parent_class
|
||||
G_DEFINE_TYPE (GstGLContext, gst_gl_context, G_TYPE_OBJECT);
|
||||
G_DEFINE_ABSTRACT_TYPE (GstGLContext, gst_gl_context, G_TYPE_OBJECT);
|
||||
|
||||
#define GST_GL_CONTEXT_GET_PRIVATE(o) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE((o), GST_GL_TYPE_CONTEXT, GstGLContextPrivate))
|
||||
|
@ -121,7 +134,6 @@ gst_gl_context_new (GstGLDisplay * display)
|
|||
|
||||
user_choice = g_getenv ("GST_GL_PLATFORM");
|
||||
GST_INFO ("creating a context, user choice:%s", user_choice);
|
||||
#if 0
|
||||
#if GST_GL_HAVE_PLATFORM_EGL
|
||||
if (!context && (!user_choice || g_strstr_len (user_choice, 7, "egl")))
|
||||
context = GST_GL_CONTEXT (gst_gl_context_egl_new ());
|
||||
|
@ -130,15 +142,17 @@ gst_gl_context_new (GstGLDisplay * display)
|
|||
if (!context && (!user_choice || g_strstr_len (user_choice, 3, "glx")))
|
||||
context = GST_GL_CONTEXT (gst_gl_context_glx_new ());
|
||||
#endif
|
||||
#if GST_GL_HAVE_PLATFORM_WIN32
|
||||
if (!context && (!user_choice || g_strstr_len (user_choice, 5, "win32")))
|
||||
context = GST_GL_CONTEXT (gst_gl_context_win32_new ());
|
||||
#endif
|
||||
#if GST_GL_HAVE_PLATFORM_COCOA
|
||||
if (!context && (!user_choice || g_strstr_len (user_choice, 5, "cocoa"))) {
|
||||
context = GST_GL_CONTEXT (gst_gl_context_cocoa_new ());
|
||||
}
|
||||
#endif
|
||||
#if GST_GL_HAVE_PLATFORM_WGL
|
||||
if (!context && (!user_choice || g_strstr_len (user_choice, 3, "wgl"))) {
|
||||
context = GST_GL_CONTEXT (gst_gl_context_wgl_new ());
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!context) {
|
||||
/* subclass returned a NULL context */
|
||||
GST_WARNING ("Could not create context. user specified %s",
|
||||
|
@ -146,9 +160,6 @@ gst_gl_context_new (GstGLDisplay * display)
|
|||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
context = g_object_new (GST_GL_TYPE_CONTEXT, NULL);
|
||||
|
||||
context->priv->display = display;
|
||||
|
||||
|
@ -164,9 +175,13 @@ gst_gl_context_finalize (GObject * object)
|
|||
gst_gl_window_set_draw_callback (context->window, NULL, NULL, NULL);
|
||||
|
||||
if (context->priv->alive) {
|
||||
g_mutex_lock (&context->priv->render_lock);
|
||||
GST_INFO ("send quit gl window loop");
|
||||
gst_gl_window_quit (context->window);
|
||||
g_cond_wait (&context->priv->destroy_cond, &context->priv->render_lock);
|
||||
while (context->priv->alive) {
|
||||
g_cond_wait (&context->priv->destroy_cond, &context->priv->render_lock);
|
||||
}
|
||||
g_mutex_unlock (&context->priv->render_lock);
|
||||
}
|
||||
|
||||
gst_gl_window_set_close_callback (context->window, NULL, NULL, NULL);
|
||||
|
@ -189,18 +204,17 @@ gst_gl_context_finalize (GObject * object)
|
|||
G_OBJECT_CLASS (gst_gl_context_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
/* FIXME move the relevant window vfuncs into GstGLContext */
|
||||
gboolean
|
||||
gst_gl_context_activate (GstGLContext * context, gboolean activate)
|
||||
{
|
||||
GstGLWindowClass *window_class;
|
||||
GstGLContextClass *context_class;
|
||||
gboolean result;
|
||||
|
||||
g_return_val_if_fail (GST_GL_IS_CONTEXT (context), FALSE);
|
||||
window_class = GST_GL_WINDOW_GET_CLASS (context->window);
|
||||
g_return_val_if_fail (window_class->activate != NULL, FALSE);
|
||||
context_class = GST_GL_CONTEXT_GET_CLASS (context);
|
||||
g_return_val_if_fail (context_class->activate != NULL, FALSE);
|
||||
|
||||
result = window_class->activate (context->window, activate);
|
||||
result = context_class->activate (context, activate);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -208,26 +222,26 @@ gst_gl_context_activate (GstGLContext * context, gboolean activate)
|
|||
GstGLAPI
|
||||
gst_gl_context_get_gl_api (GstGLContext * context)
|
||||
{
|
||||
GstGLWindowClass *window_class;
|
||||
GstGLContextClass *context_class;
|
||||
|
||||
g_return_val_if_fail (GST_GL_IS_CONTEXT (context), GST_GL_API_NONE);
|
||||
window_class = GST_GL_WINDOW_GET_CLASS (context->window);
|
||||
g_return_val_if_fail (window_class->get_gl_api != NULL, GST_GL_API_NONE);
|
||||
context_class = GST_GL_CONTEXT_GET_CLASS (context);
|
||||
g_return_val_if_fail (context_class->get_gl_api != NULL, GST_GL_API_NONE);
|
||||
|
||||
return window_class->get_gl_api (context->window);
|
||||
return context_class->get_gl_api (context);
|
||||
}
|
||||
|
||||
gpointer
|
||||
gst_gl_context_get_proc_address (GstGLContext * context, const gchar * name)
|
||||
{
|
||||
gpointer ret;
|
||||
GstGLWindowClass *window_class;
|
||||
GstGLContextClass *context_class;
|
||||
|
||||
g_return_val_if_fail (GST_GL_IS_CONTEXT (context), NULL);
|
||||
window_class = GST_GL_WINDOW_GET_CLASS (context->window);
|
||||
g_return_val_if_fail (window_class->get_proc_address != NULL, NULL);
|
||||
context_class = GST_GL_CONTEXT_GET_CLASS (context);
|
||||
g_return_val_if_fail (context_class->get_proc_address != NULL, NULL);
|
||||
|
||||
ret = window_class->get_proc_address (context->window, name);
|
||||
ret = context_class->get_proc_address (context, name);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -288,21 +302,13 @@ gst_gl_context_create (GstGLContext * context,
|
|||
guintptr external_gl_context, GError ** error)
|
||||
{
|
||||
gboolean alive = FALSE;
|
||||
GstGLWindowClass *window_class;
|
||||
|
||||
g_return_val_if_fail (GST_GL_IS_CONTEXT (context), FALSE);
|
||||
window_class = GST_GL_WINDOW_GET_CLASS (context->window);
|
||||
g_return_val_if_fail (window_class->create_context != NULL, FALSE);
|
||||
|
||||
_ensure_window (context);
|
||||
|
||||
g_mutex_lock (&context->priv->render_lock);
|
||||
|
||||
if (window_class->open) {
|
||||
if (!(alive = window_class->open (context->window, error)))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!context->priv->created) {
|
||||
context->priv->external_gl_context = external_gl_context;
|
||||
context->priv->error = error;
|
||||
|
@ -321,7 +327,6 @@ gst_gl_context_create (GstGLContext * context,
|
|||
|
||||
g_mutex_unlock (&context->priv->render_lock);
|
||||
|
||||
out:
|
||||
return alive;
|
||||
}
|
||||
|
||||
|
@ -475,6 +480,7 @@ _parse_gl_api (const gchar * apis_s)
|
|||
static gpointer
|
||||
gst_gl_context_create_thread (GstGLContext * context)
|
||||
{
|
||||
GstGLContextClass *context_class;
|
||||
GstGLWindowClass *window_class;
|
||||
GstGLDisplay *display;
|
||||
GstGLFuncs *gl;
|
||||
|
@ -488,9 +494,12 @@ gst_gl_context_create_thread (GstGLContext * context)
|
|||
GError **error;
|
||||
guintptr external_gl_context;
|
||||
|
||||
g_mutex_lock (&context->priv->render_lock);
|
||||
|
||||
error = context->priv->error;
|
||||
external_gl_context = context->priv->external_gl_context;
|
||||
|
||||
context_class = GST_GL_CONTEXT_GET_CLASS (context);
|
||||
window_class = GST_GL_WINDOW_GET_CLASS (context->window);
|
||||
|
||||
if (window_class->open) {
|
||||
|
@ -518,17 +527,34 @@ gst_gl_context_create_thread (GstGLContext * context)
|
|||
goto failure;
|
||||
}
|
||||
|
||||
if (context_class->choose_format &&
|
||||
!context_class->choose_format (context, error)) {
|
||||
g_assert (error == NULL || *error != NULL);
|
||||
g_free (compiled_api_s);
|
||||
g_free (user_api_string);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
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 (context->window, compiled_api & user_api,
|
||||
if (!context_class->create_context (context, compiled_api & user_api,
|
||||
external_gl_context, error)) {
|
||||
g_assert (error == NULL || *error != NULL);
|
||||
g_free (compiled_api_s);
|
||||
g_free (user_api_string);
|
||||
goto failure;
|
||||
}
|
||||
GST_INFO ("context created context");
|
||||
GST_INFO ("created context");
|
||||
|
||||
if (!context_class->activate (context, TRUE)) {
|
||||
g_set_error (error, GST_GL_CONTEXT_ERROR,
|
||||
GST_GL_CONTEXT_ERROR_RESOURCE_UNAVAILABLE,
|
||||
"Failed to activate the GL Context");
|
||||
g_free (compiled_api_s);
|
||||
g_free (user_api_string);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
display->gl_api = gst_gl_context_get_gl_api (context);
|
||||
g_assert (display->gl_api != GST_GL_API_NONE
|
||||
|
|
|
@ -36,7 +36,7 @@ G_BEGIN_DECLS
|
|||
GType gst_gl_context_get_type (void);
|
||||
|
||||
#define GST_GL_CONTEXT_ERROR (gst_gl_context_error_quark ())
|
||||
GQuark gst_gl_window_error_quark (void);
|
||||
GQuark gst_gl_context_error_quark (void);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
@ -69,8 +69,11 @@ struct _GstGLContextClass {
|
|||
GstGLAPI (*get_gl_api) (GstGLContext *context);
|
||||
gpointer (*get_proc_address) (GstGLContext *context, const gchar *name);
|
||||
gboolean (*activate) (GstGLContext *context, gboolean activate);
|
||||
gboolean (*choose_format) (GstGLContext *context, GError **error);
|
||||
gboolean (*create_context) (GstGLContext *context, GstGLAPI gl_api,
|
||||
guintptr external_gl_context, GError ** error);
|
||||
void (*destroy_context) (GstGLContext *context);
|
||||
void (*swap_buffers) (GstGLContext *context);
|
||||
|
||||
/*< private >*/
|
||||
gpointer _reserved[GST_PADDING];
|
||||
|
|
|
@ -22,11 +22,70 @@
|
|||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "gl.h"
|
||||
#include "gstglegl.h"
|
||||
#include <gst/gl/gl.h>
|
||||
|
||||
#if GST_GL_HAVE_WINDOW_X11
|
||||
#include "x11/gstglwindow_x11.h"
|
||||
#endif
|
||||
#if GST_GL_HAVE_WINDOW_WIN32
|
||||
#include "win32/gstglwindow_win32.h"
|
||||
#endif
|
||||
|
||||
static gboolean gst_gl_context_egl_create_context (GstGLContext * context,
|
||||
GstGLAPI gl_api, guintptr external_gl_context, GError ** error);
|
||||
static void gst_gl_context_egl_destroy_context (GstGLContext * context);
|
||||
static gboolean gst_gl_context_egl_choose_format (GstGLContext * context,
|
||||
GError ** error);
|
||||
|
||||
static gboolean gst_gl_context_egl_activate (GstGLContext * context,
|
||||
gboolean activate);
|
||||
static void gst_gl_context_egl_swap_buffers (GstGLContext * context);
|
||||
static guintptr gst_gl_context_egl_get_gl_context (GstGLContext * context);
|
||||
static GstGLAPI gst_gl_context_egl_get_gl_api (GstGLContext * context);
|
||||
static gpointer gst_gl_context_egl_get_proc_address (GstGLContext * context,
|
||||
const gchar * name);
|
||||
|
||||
G_DEFINE_TYPE (GstGLContextEGL, gst_gl_context_egl, GST_GL_TYPE_CONTEXT);
|
||||
|
||||
static void
|
||||
gst_gl_context_egl_class_init (GstGLContextEGLClass * klass)
|
||||
{
|
||||
GstGLContextClass *context_class = (GstGLContextClass *) klass;
|
||||
|
||||
context_class->get_gl_context =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_context_egl_get_gl_context);
|
||||
context_class->activate = GST_DEBUG_FUNCPTR (gst_gl_context_egl_activate);
|
||||
context_class->create_context =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_context_egl_create_context);
|
||||
context_class->destroy_context =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_context_egl_destroy_context);
|
||||
context_class->choose_format =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_context_egl_choose_format);
|
||||
context_class->swap_buffers =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_context_egl_swap_buffers);
|
||||
|
||||
context_class->get_gl_api = GST_DEBUG_FUNCPTR (gst_gl_context_egl_get_gl_api);
|
||||
context_class->get_proc_address =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_context_egl_get_proc_address);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_context_egl_init (GstGLContextEGL * context)
|
||||
{
|
||||
}
|
||||
|
||||
/* Must be called in the gl thread */
|
||||
GstGLContextEGL *
|
||||
gst_gl_context_egl_new (void)
|
||||
{
|
||||
GstGLContextEGL *window = g_object_new (GST_GL_TYPE_CONTEXT_EGL, NULL);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
gst_gl_egl_get_error_string (void)
|
||||
gst_gl_context_egl_get_error_string (void)
|
||||
{
|
||||
EGLint nErr = eglGetError ();
|
||||
|
||||
|
@ -65,7 +124,33 @@ gst_gl_egl_get_error_string (void)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
gst_gl_egl_choose_config (GstGLEGL * egl, GError ** error)
|
||||
gst_gl_context_egl_choose_format (GstGLContext * context, GError ** error)
|
||||
{
|
||||
#if GST_GL_HAVE_WINDOW_X11
|
||||
if (GST_GL_IS_WINDOW_X11 (context->window)) {
|
||||
GstGLWindow *window = gst_gl_context_get_window (context);
|
||||
GstGLWindowX11 *window_x11 = GST_GL_WINDOW_X11 (window);
|
||||
gint ret;
|
||||
|
||||
window_x11->visual_info = g_new0 (XVisualInfo, 1);
|
||||
ret = XMatchVisualInfo (window_x11->device, window_x11->screen_num,
|
||||
window_x11->depth, TrueColor, window_x11->visual_info);
|
||||
|
||||
gst_object_unref (window);
|
||||
|
||||
if (ret == 0) {
|
||||
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_WRONG_CONFIG,
|
||||
"Failed to match XVisualInfo");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_gl_context_egl_choose_config (GstGLContextEGL * egl, GError ** error)
|
||||
{
|
||||
EGLint numConfigs;
|
||||
gint i = 0;
|
||||
|
@ -87,9 +172,9 @@ gst_gl_egl_choose_config (GstGLEGL * egl, GError ** error)
|
|||
GST_INFO ("config set: %ld, %ld", (gulong) egl->egl_config,
|
||||
(gulong) numConfigs);
|
||||
} else {
|
||||
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_WRONG_CONFIG,
|
||||
g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_CONFIG,
|
||||
"Failed to set window configuration: %s",
|
||||
gst_gl_egl_get_error_string ());
|
||||
gst_gl_context_egl_get_error_string ());
|
||||
goto failure;
|
||||
}
|
||||
|
||||
|
@ -99,11 +184,13 @@ failure:
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
GstGLEGL *
|
||||
gst_gl_egl_create_context (EGLDisplay display, EGLNativeWindowType window,
|
||||
static gboolean
|
||||
gst_gl_context_egl_create_context (GstGLContext * context,
|
||||
GstGLAPI gl_api, guintptr external_gl_context, GError ** error)
|
||||
{
|
||||
GstGLEGL *egl;
|
||||
GstGLContextEGL *egl;
|
||||
GstGLWindow *window = NULL;
|
||||
EGLNativeWindowType window_handle;
|
||||
gint i = 0;
|
||||
EGLint context_attrib[3];
|
||||
EGLint majorVersion;
|
||||
|
@ -111,23 +198,25 @@ gst_gl_egl_create_context (EGLDisplay display, EGLNativeWindowType window,
|
|||
const gchar *egl_exts;
|
||||
gboolean need_surface = TRUE;
|
||||
|
||||
egl = g_slice_new0 (GstGLEGL);
|
||||
egl = GST_GL_CONTEXT_EGL (context);
|
||||
window = gst_gl_context_get_window (context);
|
||||
|
||||
if ((gl_api & GST_GL_API_OPENGL) == GST_GL_API_NONE &&
|
||||
(gl_api & GST_GL_API_GLES2) == GST_GL_API_NONE) {
|
||||
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_WRONG_API,
|
||||
g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_API,
|
||||
"xEGL supports opengl or gles2");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
egl->egl_display = display;
|
||||
egl->egl_display =
|
||||
eglGetDisplay ((EGLNativeDisplayType) gst_gl_window_get_display (window));
|
||||
|
||||
if (eglInitialize (egl->egl_display, &majorVersion, &minorVersion)) {
|
||||
GST_INFO ("egl initialized, version: %d.%d", majorVersion, minorVersion);
|
||||
} else {
|
||||
g_set_error (error, GST_GL_WINDOW_ERROR,
|
||||
GST_GL_WINDOW_ERROR_RESOURCE_UNAVAILABLE,
|
||||
"Failed to initialize egl: %s", gst_gl_egl_get_error_string ());
|
||||
g_set_error (error, GST_GL_CONTEXT_ERROR,
|
||||
GST_GL_CONTEXT_ERROR_RESOURCE_UNAVAILABLE,
|
||||
"Failed to initialize egl: %s", gst_gl_context_egl_get_error_string ());
|
||||
goto failure;
|
||||
}
|
||||
|
||||
|
@ -135,7 +224,7 @@ gst_gl_egl_create_context (EGLDisplay display, EGLNativeWindowType window,
|
|||
/* egl + opengl only available with EGL 1.4+ */
|
||||
if (majorVersion == 1 && minorVersion <= 3) {
|
||||
if ((gl_api & ~GST_GL_API_OPENGL) == GST_GL_API_NONE) {
|
||||
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_OLD_LIBS,
|
||||
g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_OLD_LIBS,
|
||||
"EGL version (%i.%i) too old for OpenGL support, (needed at least 1.4)",
|
||||
majorVersion, minorVersion);
|
||||
goto failure;
|
||||
|
@ -146,8 +235,8 @@ gst_gl_egl_create_context (EGLDisplay display, EGLNativeWindowType window,
|
|||
if (gl_api & GST_GL_API_GLES2) {
|
||||
goto try_gles2;
|
||||
} else {
|
||||
g_set_error (error, GST_GL_WINDOW_ERROR,
|
||||
GST_GL_WINDOW_ERROR_WRONG_CONFIG,
|
||||
g_set_error (error, GST_GL_CONTEXT_ERROR,
|
||||
GST_GL_CONTEXT_ERROR_WRONG_CONFIG,
|
||||
"Failed to choose a suitable OpenGL API");
|
||||
goto failure;
|
||||
}
|
||||
|
@ -155,8 +244,9 @@ gst_gl_egl_create_context (EGLDisplay display, EGLNativeWindowType window,
|
|||
}
|
||||
|
||||
if (!eglBindAPI (EGL_OPENGL_API)) {
|
||||
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_FAILED,
|
||||
"Failed to bind OpenGL|ES API: %s", gst_gl_egl_get_error_string ());
|
||||
g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_FAILED,
|
||||
"Failed to bind OpenGL|ES API: %s",
|
||||
gst_gl_context_egl_get_error_string ());
|
||||
goto failure;
|
||||
}
|
||||
|
||||
|
@ -164,15 +254,16 @@ gst_gl_egl_create_context (EGLDisplay display, EGLNativeWindowType window,
|
|||
} else if (gl_api & GST_GL_API_GLES2) {
|
||||
try_gles2:
|
||||
if (!eglBindAPI (EGL_OPENGL_ES_API)) {
|
||||
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_FAILED,
|
||||
"Failed to bind OpenGL|ES API: %s", gst_gl_egl_get_error_string ());
|
||||
g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_FAILED,
|
||||
"Failed to bind OpenGL|ES API: %s",
|
||||
gst_gl_context_egl_get_error_string ());
|
||||
goto failure;
|
||||
}
|
||||
|
||||
egl->gl_api = GST_GL_API_GLES2;
|
||||
}
|
||||
|
||||
if (!gst_gl_egl_choose_config (egl, error)) {
|
||||
if (!gst_gl_context_egl_choose_config (egl, error)) {
|
||||
g_assert (error == NULL || *error != NULL);
|
||||
goto failure;
|
||||
}
|
||||
|
@ -192,18 +283,33 @@ gst_gl_egl_create_context (EGLDisplay display, EGLNativeWindowType window,
|
|||
if (egl->egl_context != EGL_NO_CONTEXT) {
|
||||
GST_INFO ("gl context created: %ld", (gulong) egl->egl_context);
|
||||
} else {
|
||||
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_CREATE_CONTEXT,
|
||||
g_set_error (error, GST_GL_CONTEXT_ERROR,
|
||||
GST_GL_CONTEXT_ERROR_CREATE_CONTEXT,
|
||||
"Failed to create a OpenGL context: %s",
|
||||
gst_gl_egl_get_error_string ());
|
||||
gst_gl_context_egl_get_error_string ());
|
||||
goto failure;
|
||||
}
|
||||
|
||||
egl_exts = eglQueryString (egl->egl_display, EGL_EXTENSIONS);
|
||||
|
||||
if (window) {
|
||||
/* FIXME do we want a window vfunc ? */
|
||||
#if GST_GL_HAVE_WINDOW_X11
|
||||
if (GST_GL_IS_WINDOW_X11 (context->window)) {
|
||||
gst_gl_window_x11_create_window ((GstGLWindowX11 *) context->window);
|
||||
}
|
||||
#endif
|
||||
#if GST_GL_HAVE_WINDOW_WIN32
|
||||
if (GST_GL_IS_WINDOW_WIN32 (context->window)) {
|
||||
gst_gl_window_win32_create_window ((GstGLWindowWin32 *) context->window);
|
||||
}
|
||||
#endif
|
||||
|
||||
window_handle = gst_gl_window_get_window_handle (window);
|
||||
|
||||
if (window_handle) {
|
||||
egl->egl_surface =
|
||||
eglCreateWindowSurface (egl->egl_display, egl->egl_config, window,
|
||||
NULL);
|
||||
eglCreateWindowSurface (egl->egl_display, egl->egl_config,
|
||||
window_handle, NULL);
|
||||
} else if (!gst_gl_check_extension ("EGL_KHR_surfaceless_context", egl_exts)) {
|
||||
EGLint surface_attrib[7];
|
||||
gint j = 0;
|
||||
|
@ -230,27 +336,32 @@ gst_gl_egl_create_context (EGLDisplay display, EGLNativeWindowType window,
|
|||
if (egl->egl_surface != EGL_NO_SURFACE) {
|
||||
GST_INFO ("surface created");
|
||||
} else {
|
||||
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_FAILED,
|
||||
g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_FAILED,
|
||||
"Failed to create window surface: %s",
|
||||
gst_gl_egl_get_error_string ());
|
||||
gst_gl_context_egl_get_error_string ());
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
|
||||
gst_gl_egl_activate (egl, TRUE);
|
||||
gst_object_unref (window);
|
||||
|
||||
return egl;
|
||||
return TRUE;
|
||||
|
||||
failure:
|
||||
gst_gl_egl_destroy_context (egl);
|
||||
if (window)
|
||||
gst_object_unref (window);
|
||||
|
||||
return NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
gst_gl_egl_destroy_context (GstGLEGL * egl)
|
||||
static void
|
||||
gst_gl_context_egl_destroy_context (GstGLContext * context)
|
||||
{
|
||||
gst_gl_egl_activate (egl, FALSE);
|
||||
GstGLContextEGL *egl;
|
||||
|
||||
egl = GST_GL_CONTEXT_EGL (context);
|
||||
|
||||
gst_gl_context_egl_activate (context, FALSE);
|
||||
|
||||
if (egl->egl_surface)
|
||||
eglDestroySurface (egl->egl_surface, egl->egl_display);
|
||||
|
@ -262,15 +373,16 @@ gst_gl_egl_destroy_context (GstGLEGL * egl)
|
|||
eglTerminate (egl->egl_display);
|
||||
eglReleaseThread ();
|
||||
}
|
||||
|
||||
g_slice_free (GstGLEGL, egl);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_gl_egl_activate (GstGLEGL * egl, gboolean activate)
|
||||
static gboolean
|
||||
gst_gl_context_egl_activate (GstGLContext * context, gboolean activate)
|
||||
{
|
||||
GstGLContextEGL *egl;
|
||||
gboolean result;
|
||||
|
||||
egl = GST_GL_CONTEXT_EGL (context);
|
||||
|
||||
if (activate)
|
||||
result = eglMakeCurrent (egl->egl_display, egl->egl_surface,
|
||||
egl->egl_surface, egl->egl_context);
|
||||
|
@ -281,26 +393,30 @@ gst_gl_egl_activate (GstGLEGL * egl, gboolean activate)
|
|||
return result;
|
||||
}
|
||||
|
||||
guintptr
|
||||
gst_gl_egl_get_gl_context (GstGLEGL * egl)
|
||||
static guintptr
|
||||
gst_gl_context_egl_get_gl_context (GstGLContext * context)
|
||||
{
|
||||
return (guintptr) egl->egl_context;
|
||||
return (guintptr) GST_GL_CONTEXT_EGL (context)->egl_context;
|
||||
}
|
||||
|
||||
void
|
||||
gst_gl_egl_swap_buffers (GstGLEGL * egl)
|
||||
static void
|
||||
gst_gl_context_egl_swap_buffers (GstGLContext * context)
|
||||
{
|
||||
GstGLContextEGL *egl;
|
||||
|
||||
egl = GST_GL_CONTEXT_EGL (context);
|
||||
|
||||
eglSwapBuffers (egl->egl_display, egl->egl_surface);
|
||||
}
|
||||
|
||||
GstGLAPI
|
||||
gst_gl_egl_get_gl_api (GstGLEGL * egl)
|
||||
static GstGLAPI
|
||||
gst_gl_context_egl_get_gl_api (GstGLContext * context)
|
||||
{
|
||||
return egl->gl_api;
|
||||
return GST_GL_CONTEXT_EGL (context)->gl_api;
|
||||
}
|
||||
|
||||
gpointer
|
||||
gst_gl_egl_get_proc_address (GstGLEGL * egl, const gchar * name)
|
||||
static gpointer
|
||||
gst_gl_context_egl_get_proc_address (GstGLContext * context, const gchar * name)
|
||||
{
|
||||
gpointer result;
|
||||
|
||||
|
@ -309,7 +425,9 @@ gst_gl_egl_get_proc_address (GstGLEGL * egl, const gchar * name)
|
|||
return NULL;
|
||||
#endif
|
||||
|
||||
result = eglGetProcAddress (name);
|
||||
if (!(result = eglGetProcAddress (name))) {
|
||||
result = gst_gl_context_default_get_proc_address (context, name);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -25,12 +25,23 @@
|
|||
#include <EGL/egl.h>
|
||||
|
||||
#include <gst/gl/gstgl_fwd.h>
|
||||
#include <gst/gl/gstglcontext.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstGLEGL GstGLEGL;
|
||||
typedef struct _GstGLContextEGL GstGLContextEGL;
|
||||
typedef struct _GstGLContextEGLClass GstGLContextEGLClass;
|
||||
|
||||
#define GST_GL_TYPE_CONTEXT_EGL (gst_gl_context_egl_get_type())
|
||||
#define GST_GL_CONTEXT_EGL(o) (G_TYPE_CHECK_INSTANCE_CAST((o), GST_GL_TYPE_CONTEXT_EGL, GstGLContextEGL))
|
||||
#define GST_GL_CONTEXT_EGL_CLASS(k) (G_TYPE_CHECK_CLASS((k), GST_GL_TYPE_CONTEXT_EGL, GstGLContextEGLClass))
|
||||
#define GST_GL_IS_CONTEXT_EGL(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), GST_GL_TYPE_CONTEXT_EGL))
|
||||
#define GST_GL_IS_CONTEXT_EGL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), GST_GL_TYPE_CONTEXT_EGL))
|
||||
#define GST_GL_CONTEXT_EGL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_GL_TYPE_CONTEXT_EGL, GstGLContextEGLClass))
|
||||
|
||||
struct _GstGLContextEGL {
|
||||
GstGLContext context;
|
||||
|
||||
struct _GstGLEGL {
|
||||
EGLContext egl_context;
|
||||
EGLDisplay egl_display;
|
||||
EGLSurface egl_surface;
|
||||
|
@ -39,16 +50,12 @@ struct _GstGLEGL {
|
|||
GstGLAPI gl_api;
|
||||
};
|
||||
|
||||
GstGLEGL * gst_gl_egl_create_context (EGLDisplay display, EGLNativeWindowType window, GstGLAPI gl_api, guintptr external_gl_context, GError ** error);
|
||||
void gst_gl_egl_destroy_context (GstGLEGL *egl);
|
||||
struct _GstGLContextEGLClass {
|
||||
GstGLContextClass parent;
|
||||
};
|
||||
|
||||
gboolean gst_gl_egl_activate (GstGLEGL *egl, gboolean activate);
|
||||
void gst_gl_egl_swap_buffers (GstGLEGL *egl);
|
||||
|
||||
guintptr gst_gl_egl_get_gl_context (GstGLEGL *egl);
|
||||
GstGLAPI gst_gl_egl_get_gl_api (GstGLEGL *egl);
|
||||
|
||||
gpointer gst_gl_egl_get_proc_address (GstGLEGL *egl, const gchar * name);
|
||||
GType gst_gl_context_egl_get_type (void);
|
||||
GstGLContextEGL * gst_gl_context_egl_new (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#include "gl.h"
|
||||
#include "gstglwindow.h"
|
||||
|
||||
/* FIXME make this work with windowless contexts */
|
||||
|
||||
#if GST_GL_HAVE_WINDOW_X11
|
||||
#include "x11/gstglwindow_x11.h"
|
||||
#endif
|
||||
|
@ -170,40 +172,6 @@ gst_gl_window_finalize (GObject * object)
|
|||
G_OBJECT_CLASS (gst_gl_window_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
guintptr
|
||||
gst_gl_window_get_gl_context (GstGLWindow * window)
|
||||
{
|
||||
GstGLWindowClass *window_class;
|
||||
guintptr result;
|
||||
|
||||
g_return_val_if_fail (GST_GL_IS_WINDOW (window), 0);
|
||||
window_class = GST_GL_WINDOW_GET_CLASS (window);
|
||||
g_return_val_if_fail (window_class->get_gl_context != NULL, 0);
|
||||
|
||||
GST_GL_WINDOW_LOCK (window);
|
||||
result = window_class->get_gl_context (window);
|
||||
GST_GL_WINDOW_UNLOCK (window);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_gl_window_activate (GstGLWindow * window, gboolean activate)
|
||||
{
|
||||
GstGLWindowClass *window_class;
|
||||
gboolean result;
|
||||
|
||||
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->activate != NULL, FALSE);
|
||||
|
||||
GST_GL_WINDOW_LOCK (window);
|
||||
result = window_class->activate (window, activate);
|
||||
GST_GL_WINDOW_UNLOCK (window);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
gst_gl_window_set_window_handle (GstGLWindow * window, guintptr handle)
|
||||
{
|
||||
|
@ -369,41 +337,48 @@ gst_gl_window_set_close_callback (GstGLWindow * window, GstGLWindowCB callback,
|
|||
GST_GL_WINDOW_UNLOCK (window);
|
||||
}
|
||||
|
||||
GstGLAPI
|
||||
gst_gl_window_get_gl_api (GstGLWindow * window)
|
||||
gboolean
|
||||
gst_gl_window_is_running (GstGLWindow * window)
|
||||
{
|
||||
GstGLWindowClass *window_class;
|
||||
|
||||
g_return_val_if_fail (GST_GL_IS_WINDOW (window), GST_GL_API_NONE);
|
||||
window_class = GST_GL_WINDOW_GET_CLASS (window);
|
||||
g_return_val_if_fail (window_class->get_gl_api != NULL, GST_GL_API_NONE);
|
||||
|
||||
return window_class->get_gl_api (window);
|
||||
return window->priv->alive;
|
||||
}
|
||||
|
||||
gpointer
|
||||
gst_gl_window_get_proc_address (GstGLWindow * window, const gchar * name)
|
||||
guintptr
|
||||
gst_gl_window_get_display (GstGLWindow * window)
|
||||
{
|
||||
gpointer ret;
|
||||
guintptr ret;
|
||||
GstGLWindowClass *window_class;
|
||||
|
||||
g_return_val_if_fail (GST_GL_IS_WINDOW (window), NULL);
|
||||
g_return_val_if_fail (GST_GL_IS_WINDOW (window), 0);
|
||||
window_class = GST_GL_WINDOW_GET_CLASS (window);
|
||||
g_return_val_if_fail (window_class->get_proc_address != NULL, NULL);
|
||||
g_return_val_if_fail (window_class->get_display != NULL, 0);
|
||||
|
||||
GST_GL_WINDOW_LOCK (window);
|
||||
|
||||
ret = window_class->get_proc_address (window, name);
|
||||
ret = window_class->get_display (window);
|
||||
|
||||
GST_GL_WINDOW_UNLOCK (window);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_gl_window_is_running (GstGLWindow * window)
|
||||
guintptr
|
||||
gst_gl_window_get_window_handle (GstGLWindow * window)
|
||||
{
|
||||
return window->priv->alive;
|
||||
guintptr ret;
|
||||
GstGLWindowClass *window_class;
|
||||
|
||||
g_return_val_if_fail (GST_GL_IS_WINDOW (window), 0);
|
||||
window_class = GST_GL_WINDOW_GET_CLASS (window);
|
||||
g_return_val_if_fail (window_class->get_window_handle != NULL, 0);
|
||||
|
||||
GST_GL_WINDOW_LOCK (window);
|
||||
|
||||
ret = window_class->get_window_handle (window);
|
||||
|
||||
GST_GL_WINDOW_UNLOCK (window);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
GstGLContext *
|
||||
|
|
|
@ -99,14 +99,9 @@ struct _GstGLWindowClass {
|
|||
/*< private >*/
|
||||
GObjectClass parent_class;
|
||||
|
||||
guintptr (*get_gl_context) (GstGLWindow *window);
|
||||
GstGLAPI (*get_gl_api) (GstGLWindow *window);
|
||||
gpointer (*get_proc_address) (GstGLWindow *window, const gchar *name);
|
||||
gboolean (*activate) (GstGLWindow *window, gboolean activate);
|
||||
guintptr (*get_display) (GstGLWindow *window);
|
||||
void (*set_window_handle) (GstGLWindow *window, guintptr id);
|
||||
gboolean (*create_context) (GstGLWindow *window, GstGLAPI gl_api,
|
||||
guintptr external_gl_context, GError ** error);
|
||||
gboolean (*share_context) (GstGLWindow *window, guintptr external_gl_context);
|
||||
guintptr (*get_window_handle) (GstGLWindow *window);
|
||||
void (*draw_unlocked) (GstGLWindow *window, guint width, guint height);
|
||||
void (*draw) (GstGLWindow *window, guint width, guint height);
|
||||
void (*run) (GstGLWindow *window);
|
||||
|
@ -132,7 +127,6 @@ void gst_gl_window_set_resize_callback (GstGLWindow *window, GstGLWindowRes
|
|||
void gst_gl_window_set_close_callback (GstGLWindow *window, GstGLWindowCB callback, gpointer data, GDestroyNotify destroy_notify);
|
||||
void gst_gl_window_set_need_lock (GstGLWindow *window, gboolean need_lock);
|
||||
|
||||
guintptr gst_gl_window_get_gl_context (GstGLWindow *window);
|
||||
void gst_gl_window_set_window_handle (GstGLWindow *window, guintptr handle);
|
||||
guintptr gst_gl_window_get_window_handle (GstGLWindow *window);
|
||||
void gst_gl_window_draw_unlocked (GstGLWindow *window, guint width, guint height);
|
||||
|
@ -140,6 +134,7 @@ void gst_gl_window_draw (GstGLWindow *window, guint width, g
|
|||
void gst_gl_window_run (GstGLWindow *window);
|
||||
void gst_gl_window_quit (GstGLWindow *window);
|
||||
void gst_gl_window_send_message (GstGLWindow *window, GstGLWindowCB callback, gpointer data);
|
||||
guintptr gst_gl_window_get_display (GstGLWindow *window);
|
||||
|
||||
GstGLContext * gst_gl_window_get_context (GstGLWindow *window);
|
||||
|
||||
|
|
|
@ -40,9 +40,8 @@ const gchar *WlEGLErrorString ();
|
|||
G_DEFINE_TYPE (GstGLWindowWaylandEGL, gst_gl_window_wayland_egl,
|
||||
GST_GL_TYPE_WINDOW);
|
||||
|
||||
static guintptr gst_gl_window_wayland_egl_get_gl_context (GstGLWindow * window);
|
||||
static gboolean gst_gl_window_wayland_egl_activate (GstGLWindow * window,
|
||||
gboolean activate);
|
||||
static guintptr gst_gl_window_wayland_egl_get_window_handle (GstGLWindow *
|
||||
window);
|
||||
static void gst_gl_window_wayland_egl_set_window_handle (GstGLWindow * window,
|
||||
guintptr handle);
|
||||
static void gst_gl_window_wayland_egl_draw (GstGLWindow * window, guint width,
|
||||
|
@ -51,14 +50,10 @@ static void gst_gl_window_wayland_egl_run (GstGLWindow * window);
|
|||
static void gst_gl_window_wayland_egl_quit (GstGLWindow * window);
|
||||
static void gst_gl_window_wayland_egl_send_message (GstGLWindow * window,
|
||||
GstGLWindowCB callback, gpointer data);
|
||||
static void gst_gl_window_wayland_egl_destroy_context (GstGLWindowWaylandEGL *
|
||||
window_egl);
|
||||
static gboolean gst_gl_window_wayland_egl_create_context (GstGLWindow
|
||||
* window, GstGLAPI gl_api, guintptr external_gl_context, GError ** error);
|
||||
static GstGLAPI gst_gl_window_wayland_egl_get_gl_api (GstGLWindow * window);
|
||||
static gpointer gst_gl_window_wayland_egl_get_proc_address (GstGLWindow *
|
||||
window, const gchar * name);
|
||||
static void gst_gl_window_wayland_egl_close (GstGLWindow * window);
|
||||
static gboolean gst_gl_window_wayland_egl_open (GstGLWindow * window,
|
||||
GError ** error);
|
||||
static guintptr gst_gl_window_wayland_egl_get_display (GstGLWindow * window);
|
||||
|
||||
static void
|
||||
pointer_handle_enter (void *data, struct wl_pointer *pointer, uint32_t serial,
|
||||
|
@ -254,12 +249,8 @@ gst_gl_window_wayland_egl_class_init (GstGLWindowWaylandEGLClass * klass)
|
|||
{
|
||||
GstGLWindowClass *window_class = (GstGLWindowClass *) klass;
|
||||
|
||||
window_class->create_context =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_wayland_egl_create_context);
|
||||
window_class->get_gl_context =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_wayland_egl_get_gl_context);
|
||||
window_class->activate =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_wayland_egl_activate);
|
||||
window_class->get_window_handle =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_wayland_egl_get_window_handle);
|
||||
window_class->set_window_handle =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_wayland_egl_set_window_handle);
|
||||
window_class->draw_unlocked =
|
||||
|
@ -269,11 +260,10 @@ gst_gl_window_wayland_egl_class_init (GstGLWindowWaylandEGLClass * klass)
|
|||
window_class->quit = GST_DEBUG_FUNCPTR (gst_gl_window_wayland_egl_quit);
|
||||
window_class->send_message =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_wayland_egl_send_message);
|
||||
window_class->get_gl_api =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_wayland_egl_get_gl_api);
|
||||
window_class->get_proc_address =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_wayland_egl_get_proc_address);
|
||||
window_class->close = GST_DEBUG_FUNCPTR (gst_gl_window_wayland_egl_close);
|
||||
window_class->open = GST_DEBUG_FUNCPTR (gst_gl_window_wayland_egl_open);
|
||||
window_class->get_display =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_wayland_egl_get_display);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -303,7 +293,7 @@ gst_gl_window_wayland_egl_close (GstGLWindow * window)
|
|||
|
||||
window_egl = GST_GL_WINDOW_WAYLAND_EGL (window);
|
||||
|
||||
gst_gl_window_wayland_egl_destroy_context (window_egl);
|
||||
destroy_surface (window_egl);
|
||||
|
||||
if (window_egl->display.cursor_surface)
|
||||
wl_surface_destroy (window_egl->display.cursor_surface);
|
||||
|
@ -324,8 +314,10 @@ gst_gl_window_wayland_egl_close (GstGLWindow * window)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
_setup_wayland (GstGLWindowWaylandEGL * window_egl, GError ** error)
|
||||
gst_gl_window_wayland_egl_open (GstGLWindow * window, GError ** error)
|
||||
{
|
||||
GstGLWindowWaylandEGL *window_egl = GST_GL_WINDOW_WAYLAND_EGL (window);
|
||||
|
||||
window_egl->display.display = wl_display_connect (NULL);
|
||||
if (!window_egl->display.display) {
|
||||
g_set_error (error, GST_GL_WINDOW_ERROR,
|
||||
|
@ -359,78 +351,6 @@ error:
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_gl_window_wayland_egl_create_context (GstGLWindow * window,
|
||||
GstGLAPI gl_api, guintptr external_gl_context, GError ** error)
|
||||
{
|
||||
GstGLWindowWaylandEGL *window_egl = GST_GL_WINDOW_WAYLAND_EGL (window);
|
||||
if (!_setup_wayland (window_egl, error))
|
||||
return FALSE;
|
||||
|
||||
window_egl->egl =
|
||||
gst_gl_egl_create_context (eglGetDisplay ((EGLNativeDisplayType)
|
||||
window_egl->display.display), window_egl->window.native, gl_api,
|
||||
external_gl_context, error);
|
||||
if (!window_egl->egl)
|
||||
goto failure;
|
||||
|
||||
return TRUE;
|
||||
|
||||
failure:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_window_wayland_egl_destroy_context (GstGLWindowWaylandEGL * window_egl)
|
||||
{
|
||||
gst_gl_egl_activate (window_egl->egl, FALSE);
|
||||
|
||||
destroy_surface (window_egl);
|
||||
/*
|
||||
gst_gl_egl_destroy_surface (window_egl->egl);
|
||||
*/
|
||||
gst_gl_egl_destroy_context (window_egl->egl);
|
||||
window_egl->egl = NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_gl_window_wayland_egl_activate (GstGLWindow * window, gboolean activate)
|
||||
{
|
||||
GstGLWindowWaylandEGL *window_egl;
|
||||
|
||||
window_egl = GST_GL_WINDOW_WAYLAND_EGL (window);
|
||||
|
||||
return gst_gl_egl_activate (window_egl->egl, activate);
|
||||
}
|
||||
|
||||
static guintptr
|
||||
gst_gl_window_wayland_egl_get_gl_context (GstGLWindow * window)
|
||||
{
|
||||
GstGLWindowWaylandEGL *window_egl;
|
||||
|
||||
window_egl = GST_GL_WINDOW_WAYLAND_EGL (window);
|
||||
|
||||
return gst_gl_egl_get_gl_context (window_egl->egl);
|
||||
}
|
||||
|
||||
static GstGLAPI
|
||||
gst_gl_window_wayland_egl_get_gl_api (GstGLWindow * window)
|
||||
{
|
||||
GstGLWindowWaylandEGL *window_egl;
|
||||
|
||||
window_egl = GST_GL_WINDOW_WAYLAND_EGL (window);
|
||||
|
||||
return gst_gl_egl_get_gl_api (window_egl->egl);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_window_wayland_egl_swap_buffers (GstGLWindow * window)
|
||||
{
|
||||
GstGLWindowWaylandEGL *window_egl = GST_GL_WINDOW_WAYLAND_EGL (window);
|
||||
|
||||
gst_gl_egl_swap_buffers (window_egl->egl);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_window_wayland_egl_run (GstGLWindow * window)
|
||||
{
|
||||
|
@ -506,6 +426,12 @@ gst_gl_window_wayland_egl_send_message (GstGLWindow * window,
|
|||
g_mutex_unlock (&message.lock);
|
||||
}
|
||||
|
||||
static guintptr
|
||||
gst_gl_window_wayland_egl_get_window_handle (GstGLWindow * window)
|
||||
{
|
||||
return (guintptr) GST_GL_WINDOW_WAYLAND_EGL (window)->window.native;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_window_wayland_egl_set_window_handle (GstGLWindow * window,
|
||||
guintptr handle)
|
||||
|
@ -544,6 +470,8 @@ draw_cb (gpointer data)
|
|||
struct draw *draw_data = data;
|
||||
GstGLWindowWaylandEGL *window_egl = draw_data->window;
|
||||
GstGLWindow *window = GST_GL_WINDOW (window_egl);
|
||||
GstGLContext *context = gst_gl_window_get_context (window);
|
||||
GstGLContextClass *context_class = GST_GL_CONTEXT_GET_CLASS (context);
|
||||
|
||||
if (window_egl->window.window_width != draw_data->width
|
||||
|| window_egl->window.window_height != draw_data->height) {
|
||||
|
@ -556,7 +484,9 @@ draw_cb (gpointer data)
|
|||
if (window->draw)
|
||||
window->draw (window->draw_data);
|
||||
|
||||
gst_gl_window_wayland_egl_swap_buffers (window);
|
||||
context_class->swap_buffers (context);
|
||||
|
||||
gst_object_unref (context);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -571,19 +501,12 @@ gst_gl_window_wayland_egl_draw (GstGLWindow * window, guint width, guint height)
|
|||
gst_gl_window_send_message (window, (GstGLWindowCB) draw_cb, &draw_data);
|
||||
}
|
||||
|
||||
static gpointer
|
||||
gst_gl_window_wayland_egl_get_proc_address (GstGLWindow * window,
|
||||
const gchar * name)
|
||||
static guintptr
|
||||
gst_gl_window_wayland_egl_get_display (GstGLWindow * window)
|
||||
{
|
||||
GstGLContext *context = NULL;
|
||||
GstGLWindowWaylandEGL *window_egl;
|
||||
gpointer result;
|
||||
|
||||
window_egl = GST_GL_WINDOW_WAYLAND_EGL (window);
|
||||
|
||||
if (!(result = gst_gl_egl_get_proc_address (window_egl->egl, name))) {
|
||||
result = gst_gl_context_default_get_proc_address (context, name);
|
||||
}
|
||||
|
||||
return result;
|
||||
return (guintptr) window_egl->display.display;
|
||||
}
|
||||
|
|
|
@ -74,8 +74,6 @@ struct window {
|
|||
struct _GstGLWindowWaylandEGL {
|
||||
/*< private >*/
|
||||
GstGLWindow parent;
|
||||
|
||||
GstGLEGL *egl;
|
||||
|
||||
struct display display;
|
||||
struct window window;
|
||||
|
|
|
@ -9,13 +9,13 @@ noinst_HEADERS = \
|
|||
gstglwindow_win32.h
|
||||
|
||||
if USE_WGL
|
||||
libgstgl_win32_la_SOURCES += gstglwindow_win32_wgl.c
|
||||
noinst_HEADERS += gstglwindow_win32_wgl.h
|
||||
endif
|
||||
if USE_EGL
|
||||
libgstgl_win32_la_SOURCES += gstglwindow_win32_egl.c
|
||||
noinst_HEADERS += gstglwindow_win32_egl.h
|
||||
libgstgl_win32_la_SOURCES += gstglcontext_wgl.c
|
||||
noinst_HEADERS += gstglcontext_wgl.h
|
||||
endif
|
||||
#if USE_EGL
|
||||
#libgstgl_win32_la_SOURCES += gstglwindow_win32_egl.c
|
||||
#noinst_HEADERS += gstglwindow_win32_egl.h
|
||||
#endif
|
||||
|
||||
libgstgl_win32_la_CFLAGS = \
|
||||
-I$(top_srcdir)/gst-libs \
|
||||
|
|
245
gst-libs/gst/gl/win32/gstglcontext_wgl.c
Normal file
245
gst-libs/gst/gl/win32/gstglcontext_wgl.c
Normal file
|
@ -0,0 +1,245 @@
|
|||
/*
|
||||
* GStreamer
|
||||
* Copyright (C) 2008 Julien Isorce <julien.isorce@gmail.com>
|
||||
* Copyright (C) 2012 Matthew Waters <ystreet00@gmail.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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "../gstgl_fwd.h"
|
||||
#include <gst/gl/gstglcontext.h>
|
||||
|
||||
#include "gstglcontext_wgl.h"
|
||||
|
||||
#define gst_gl_context_wgl_parent_class parent_class
|
||||
G_DEFINE_TYPE (GstGLContextWGL, gst_gl_context_wgl, GST_GL_TYPE_CONTEXT);
|
||||
|
||||
static guintptr gst_gl_context_wgl_get_gl_context (GstGLContext * context);
|
||||
static void gst_gl_context_wgl_swap_buffers (GstGLContext * context);
|
||||
static gboolean gst_gl_context_wgl_choose_format (GstGLContext * context,
|
||||
GError ** error);
|
||||
static gboolean gst_gl_context_wgl_activate (GstGLContext * context,
|
||||
gboolean activate);
|
||||
static gboolean gst_gl_context_wgl_create_context (GstGLContext * context,
|
||||
GstGLAPI gl_api, guintptr external_gl_context, GError ** error);
|
||||
static void gst_gl_context_wgl_destroy_context (GstGLContext * context);
|
||||
GstGLAPI gst_gl_context_wgl_get_gl_api (GstGLContext * context);
|
||||
static gpointer gst_gl_context_wgl_get_proc_address (GstGLContext * context,
|
||||
const gchar * name);
|
||||
|
||||
static void
|
||||
gst_gl_context_wgl_class_init (GstGLContextWGLClass * klass)
|
||||
{
|
||||
GstGLContextClass *context_class = (GstGLContextClass *) klass;
|
||||
|
||||
context_class->get_gl_context =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_context_wgl_get_gl_context);
|
||||
context_class->choose_format =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_context_wgl_choose_format);
|
||||
context_class->activate = GST_DEBUG_FUNCPTR (gst_gl_context_wgl_activate);
|
||||
context_class->create_context =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_context_wgl_create_context);
|
||||
context_class->destroy_context =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_context_wgl_destroy_context);
|
||||
context_class->swap_buffers =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_context_wgl_swap_buffers);
|
||||
|
||||
context_class->get_proc_address =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_context_wgl_get_proc_address);
|
||||
context_class->get_gl_api = GST_DEBUG_FUNCPTR (gst_gl_context_wgl_get_gl_api);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_context_wgl_init (GstGLContextWGL * context_wgl)
|
||||
{
|
||||
}
|
||||
|
||||
/* Must be called in the gl thread */
|
||||
GstGLContextWGL *
|
||||
gst_gl_context_wgl_new (void)
|
||||
{
|
||||
GstGLContextWGL *context = g_object_new (GST_GL_TYPE_CONTEXT_WGL, NULL);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_gl_context_wgl_create_context (GstGLContext * context,
|
||||
GstGLAPI gl_api, guintptr external_gl_context, GError ** error)
|
||||
{
|
||||
GstGLWindow *window;
|
||||
GstGLContextWGL *context_wgl;
|
||||
HDC device;
|
||||
|
||||
context_wgl = GST_GL_CONTEXT_WGL (context);
|
||||
window = gst_gl_context_get_window (context);
|
||||
device = (HDC) gst_gl_window_get_display (window);
|
||||
|
||||
context_wgl->wgl_context = wglCreateContext (device);
|
||||
if (context_wgl->wgl_context)
|
||||
GST_DEBUG ("gl context created: %" G_GUINTPTR_FORMAT,
|
||||
(guintptr) context_wgl->wgl_context);
|
||||
else {
|
||||
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_CREATE_CONTEXT,
|
||||
"failed to create glcontext:%lu", GetLastError ());
|
||||
goto failure;
|
||||
}
|
||||
g_assert (context_wgl->wgl_context);
|
||||
|
||||
GST_LOG ("gl context id: %" G_GUINTPTR_FORMAT,
|
||||
(guintptr) context_wgl->wgl_context);
|
||||
|
||||
gst_object_unref (window);
|
||||
|
||||
return TRUE;
|
||||
|
||||
failure:
|
||||
gst_object_unref (window);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_context_wgl_destroy_context (GstGLContext * context)
|
||||
{
|
||||
GstGLContextWGL *context_wgl;
|
||||
|
||||
context_wgl = GST_GL_CONTEXT_WGL (context);
|
||||
|
||||
if (context_wgl->wgl_context)
|
||||
wglDeleteContext (context_wgl->wgl_context);
|
||||
context_wgl->wgl_context = NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_gl_context_wgl_choose_format (GstGLContext * context, GError ** error)
|
||||
{
|
||||
GstGLWindow *window;
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
gint pixelformat = 0;
|
||||
gboolean res = FALSE;
|
||||
HDC device;
|
||||
|
||||
window = gst_gl_context_get_window (context);
|
||||
gst_gl_window_win32_create_window (GST_GL_WINDOW_WIN32 (window), error);
|
||||
device = (HDC) gst_gl_window_get_display (window);
|
||||
gst_object_unref (window);
|
||||
|
||||
pfd.nSize = sizeof (PIXELFORMATDESCRIPTOR);
|
||||
pfd.nVersion = 1;
|
||||
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
|
||||
pfd.iPixelType = PFD_TYPE_RGBA;
|
||||
pfd.cColorBits = 24;
|
||||
pfd.cRedBits = 8;
|
||||
pfd.cRedShift = 0;
|
||||
pfd.cGreenBits = 8;
|
||||
pfd.cGreenShift = 0;
|
||||
pfd.cBlueBits = 8;
|
||||
pfd.cBlueShift = 0;
|
||||
pfd.cAlphaBits = 0;
|
||||
pfd.cAlphaShift = 0;
|
||||
pfd.cAccumBits = 0;
|
||||
pfd.cAccumRedBits = 0;
|
||||
pfd.cAccumGreenBits = 0;
|
||||
pfd.cAccumBlueBits = 0;
|
||||
pfd.cAccumAlphaBits = 0;
|
||||
pfd.cDepthBits = 24;
|
||||
pfd.cStencilBits = 8;
|
||||
pfd.cAuxBuffers = 0;
|
||||
pfd.iLayerType = PFD_MAIN_PLANE;
|
||||
pfd.bReserved = 0;
|
||||
pfd.dwLayerMask = 0;
|
||||
pfd.dwVisibleMask = 0;
|
||||
pfd.dwDamageMask = 0;
|
||||
|
||||
pfd.cColorBits = (BYTE) GetDeviceCaps (device, BITSPIXEL);
|
||||
|
||||
pixelformat = ChoosePixelFormat (device, &pfd);
|
||||
|
||||
if (!pixelformat) {
|
||||
g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_FAILED,
|
||||
"Failed to choose a pixel format");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
res = SetPixelFormat (device, pixelformat, &pfd);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_context_wgl_swap_buffers (GstGLContext * context)
|
||||
{
|
||||
GstGLWindow *window = gst_gl_context_get_window (context);
|
||||
HDC device = (HDC) gst_gl_window_get_display (window);
|
||||
|
||||
SwapBuffers (device);
|
||||
|
||||
gst_object_unref (window);
|
||||
}
|
||||
|
||||
static guintptr
|
||||
gst_gl_context_wgl_get_gl_context (GstGLContext * context)
|
||||
{
|
||||
return (guintptr) GST_GL_CONTEXT_WGL (context)->wgl_context;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_gl_context_wgl_activate (GstGLContext * context, gboolean activate)
|
||||
{
|
||||
GstGLWindow *window;
|
||||
GstGLContextWGL *context_wgl;
|
||||
HDC device;
|
||||
gboolean result;
|
||||
|
||||
window = gst_gl_context_get_window (context);
|
||||
context_wgl = GST_GL_CONTEXT_WGL (context);
|
||||
device = (HDC) gst_gl_window_get_display (window);
|
||||
|
||||
if (activate) {
|
||||
result = wglMakeCurrent (device, context_wgl->wgl_context);
|
||||
} else {
|
||||
result = wglMakeCurrent (NULL, NULL);
|
||||
}
|
||||
|
||||
gst_object_unref (window);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
GstGLAPI
|
||||
gst_gl_context_wgl_get_gl_api (GstGLContext * context)
|
||||
{
|
||||
return GST_GL_API_OPENGL;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
gst_gl_context_wgl_get_proc_address (GstGLContext * context, const gchar * name)
|
||||
{
|
||||
gpointer result;
|
||||
|
||||
if (!(result = wglGetProcAddress ((LPCSTR) name))) {
|
||||
result = gst_gl_context_default_get_proc_address (context, name);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
62
gst-libs/gst/gl/win32/gstglcontext_wgl.h
Normal file
62
gst-libs/gst/gl/win32/gstglcontext_wgl.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* GStreamer
|
||||
* Copyright (C) 2012 Matthew Waters <ystreet00@gmail.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 __GST_GL_CONTEXT_WGL_H__
|
||||
#define __GST_GL_CONTEXT_WGL_H__
|
||||
|
||||
#include "gstglwindow_win32.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_GL_TYPE_CONTEXT_WGL (gst_gl_context_wgl_get_type())
|
||||
#define GST_GL_CONTEXT_WGL(o) (G_TYPE_CHECK_INSTANCE_CAST((o), GST_GL_TYPE_CONTEXT_WGL, GstGLContextWGL))
|
||||
#define GST_GL_CONTEXT_WGL_CLASS(k) (G_TYPE_CHECK_CLASS((k), GST_GL_TYPE_CONTEXT_WGL, GstGLContextWGLClass))
|
||||
#define GST_GL_IS_CONTEXT_WGL(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), GST_GL_TYPE_CONTEXT_WGL))
|
||||
#define GST_GL_IS_CONTEXT_WGL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), GST_GL_TYPE_CONTEXT_WGL))
|
||||
#define GST_GL_CONTEXT_WGL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_GL_TYPE_CONTEXT_WGL, GstGLContextWGLClass))
|
||||
|
||||
typedef struct _GstGLContextWGL GstGLContextWGL;
|
||||
typedef struct _GstGLContextWGLClass GstGLContextWGLClass;
|
||||
|
||||
struct _GstGLContextWGL {
|
||||
/*< private >*/
|
||||
GstGLContext parent;
|
||||
|
||||
HGLRC wgl_context;
|
||||
HGLRC external_gl_context;
|
||||
|
||||
gpointer _reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
struct _GstGLContextWGLClass {
|
||||
/*< private >*/
|
||||
GstGLContextClass parent_class;
|
||||
|
||||
/*< private >*/
|
||||
gpointer _reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
GType gst_gl_context_wgl_get_type (void);
|
||||
|
||||
GstGLContextWGL * gst_gl_context_wgl_new (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_GL_CONTEXT_WGL_H__ */
|
|
@ -25,17 +25,9 @@
|
|||
|
||||
#include "gstglwindow_win32.h"
|
||||
|
||||
#if GST_GL_HAVE_PLATFORM_WGL
|
||||
#include "gstglwindow_win32_wgl.h"
|
||||
#endif
|
||||
#if GST_GL_HAVE_PLATFORM_EGL
|
||||
#include "gstglwindow_win32_egl.h"
|
||||
#endif
|
||||
|
||||
#define WM_GST_GL_WINDOW_CUSTOM (WM_APP+1)
|
||||
#define WM_GST_GL_WINDOW_QUIT (WM_APP+2)
|
||||
|
||||
void gst_gl_window_set_pixel_format (GstGLWindowWin32 * window);
|
||||
LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam,
|
||||
LPARAM lParam);
|
||||
LRESULT FAR PASCAL sub_class_proc (HWND hWnd, UINT uMsg, WPARAM wParam,
|
||||
|
@ -51,11 +43,7 @@ enum
|
|||
|
||||
struct _GstGLWindowWin32Private
|
||||
{
|
||||
GstGLAPI gl_api;
|
||||
guintptr external_gl_context;
|
||||
GError **error;
|
||||
gboolean activate;
|
||||
gboolean activate_result;
|
||||
gint dummy;
|
||||
};
|
||||
|
||||
#define GST_CAT_DEFAULT gst_gl_window_win32_debug
|
||||
|
@ -67,20 +55,14 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
|||
G_DEFINE_TYPE_WITH_CODE (GstGLWindowWin32, gst_gl_window_win32,
|
||||
GST_GL_TYPE_WINDOW, DEBUG_INIT);
|
||||
|
||||
HHOOK hHook;
|
||||
|
||||
gboolean gst_gl_window_win32_create_context (GstGLWindow * window,
|
||||
GstGLAPI gl_api, guintptr external_gl_context, GError ** error);
|
||||
guintptr gst_gl_window_win32_get_gl_context (GstGLWindow * window);
|
||||
gboolean gst_gl_window_win32_activate (GstGLWindow * window, gboolean activate);
|
||||
void gst_gl_window_win32_set_window_handle (GstGLWindow * window,
|
||||
static void gst_gl_window_win32_set_window_handle (GstGLWindow * window,
|
||||
guintptr handle);
|
||||
void gst_gl_window_win32_draw_unlocked (GstGLWindow * window, guint width,
|
||||
static guintptr gst_gl_window_win32_get_display (GstGLWindow * window);
|
||||
static void gst_gl_window_win32_draw (GstGLWindow * window, guint width,
|
||||
guint height);
|
||||
void gst_gl_window_win32_draw (GstGLWindow * window, guint width, guint height);
|
||||
void gst_gl_window_win32_run (GstGLWindow * window);
|
||||
void gst_gl_window_win32_quit (GstGLWindow * window);
|
||||
void gst_gl_window_win32_send_message (GstGLWindow * window,
|
||||
static void gst_gl_window_win32_run (GstGLWindow * window);
|
||||
static void gst_gl_window_win32_quit (GstGLWindow * window);
|
||||
static void gst_gl_window_win32_send_message (GstGLWindow * window,
|
||||
GstGLWindowCB callback, gpointer data);
|
||||
|
||||
static void
|
||||
|
@ -90,11 +72,6 @@ gst_gl_window_win32_class_init (GstGLWindowWin32Class * klass)
|
|||
|
||||
g_type_class_add_private (klass, sizeof (GstGLWindowWin32Private));
|
||||
|
||||
window_class->create_context =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_win32_create_context);
|
||||
window_class->get_gl_context =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_win32_get_gl_context);
|
||||
window_class->activate = GST_DEBUG_FUNCPTR (gst_gl_window_win32_activate);
|
||||
window_class->set_window_handle =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_win32_set_window_handle);
|
||||
window_class->draw_unlocked = GST_DEBUG_FUNCPTR (gst_gl_window_win32_draw);
|
||||
|
@ -103,6 +80,8 @@ gst_gl_window_win32_class_init (GstGLWindowWin32Class * klass)
|
|||
window_class->quit = GST_DEBUG_FUNCPTR (gst_gl_window_win32_quit);
|
||||
window_class->send_message =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_win32_send_message);
|
||||
window_class->get_display =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_win32_get_display);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -117,33 +96,16 @@ gst_gl_window_win32_init (GstGLWindowWin32 * window)
|
|||
GstGLWindowWin32 *
|
||||
gst_gl_window_win32_new (void)
|
||||
{
|
||||
GstGLWindowWin32 *window = NULL;
|
||||
const gchar *user_choice;
|
||||
|
||||
user_choice = g_getenv ("GST_GL_PLATFORM");
|
||||
|
||||
#if GST_GL_HAVE_PLATFORM_WGL
|
||||
if (!window && (!user_choice || g_strstr_len (user_choice, 3, "wgl")))
|
||||
window = GST_GL_WINDOW_WIN32 (gst_gl_window_win32_wgl_new ());
|
||||
#endif
|
||||
#if GST_GL_HAVE_PLATFORM_EGL
|
||||
if (!window && (!user_choice || g_strstr_len (user_choice, 3, "egl")))
|
||||
window = GST_GL_WINDOW_WIN32 (gst_gl_window_win32_egl_new ());
|
||||
#endif
|
||||
if (!window) {
|
||||
GST_WARNING ("Failed to create win32 window, user_choice:%s",
|
||||
user_choice ? user_choice : "NULL");
|
||||
return NULL;
|
||||
}
|
||||
GstGLWindowWin32 *window = g_object_new (GST_GL_TYPE_WINDOW_WIN32, NULL);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_gl_window_win32_create_context (GstGLWindow * window, GstGLAPI gl_api,
|
||||
guintptr external_gl_context, GError ** error)
|
||||
gst_gl_window_win32_create_window (GstGLWindowWin32 * window_win32,
|
||||
GError ** error)
|
||||
{
|
||||
GstGLWindowWin32 *window_win32 = GST_GL_WINDOW_WIN32 (window);
|
||||
// GstGLWindowWin32 *window_win32 = GST_GL_WINDOW_WIN32 (window);
|
||||
WNDCLASSEX wc;
|
||||
ATOM atom = 0;
|
||||
HINSTANCE hinstance = GetModuleHandle (NULL);
|
||||
|
@ -177,7 +139,9 @@ gst_gl_window_win32_create_context (GstGLWindow * window, GstGLAPI gl_api,
|
|||
atom = RegisterClassEx (&wc);
|
||||
|
||||
if (atom == 0) {
|
||||
GST_WARNING ("Failed to register window class %lud\n", GetLastError ());
|
||||
g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_FAILED,
|
||||
"Failed to register window class 0x%x\n",
|
||||
(unsigned int) GetLastError ());
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
|
@ -187,10 +151,6 @@ gst_gl_window_win32_create_context (GstGLWindow * window, GstGLAPI gl_api,
|
|||
window_win32->is_closed = FALSE;
|
||||
window_win32->visible = FALSE;
|
||||
|
||||
window_win32->priv->gl_api = gl_api;
|
||||
window_win32->priv->external_gl_context = external_gl_context;
|
||||
window_win32->priv->error = error;
|
||||
|
||||
window_win32->internal_win_id = CreateWindowEx (0,
|
||||
"GSTGL",
|
||||
"OpenGL renderer",
|
||||
|
@ -198,16 +158,18 @@ gst_gl_window_win32_create_context (GstGLWindow * window, GstGLAPI gl_api,
|
|||
x, y, 0, 0, (HWND) NULL, (HMENU) NULL, hinstance, window_win32);
|
||||
|
||||
if (!window_win32->internal_win_id) {
|
||||
GST_DEBUG ("failed to create gl window\n");
|
||||
g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_FAILED,
|
||||
"failed to create gl window");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
GST_DEBUG ("gl window created: %" G_GUINTPTR_FORMAT "\n",
|
||||
GST_DEBUG ("gl window created: %" G_GUINTPTR_FORMAT,
|
||||
(guintptr) window_win32->internal_win_id);
|
||||
|
||||
//device is set in the window_proc
|
||||
if (!window_win32->device) {
|
||||
GST_DEBUG ("failed to create device\n");
|
||||
g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_FAILED,
|
||||
"failed to create device");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
|
@ -220,47 +182,17 @@ failure:
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
guintptr
|
||||
gst_gl_window_win32_get_gl_context (GstGLWindow * window)
|
||||
static guintptr
|
||||
gst_gl_window_win32_get_display (GstGLWindow * window)
|
||||
{
|
||||
GstGLWindowWin32Class *window_class;
|
||||
GstGLWindowWin32 *window_win32;
|
||||
|
||||
window_class = GST_GL_WINDOW_WIN32_GET_CLASS (window);
|
||||
window_win32 = GST_GL_WINDOW_WIN32 (window);
|
||||
|
||||
return window_class->get_gl_context (GST_GL_WINDOW_WIN32 (window));
|
||||
return (guintptr) window_win32->device;
|
||||
}
|
||||
|
||||
static void
|
||||
callback_activate (GstGLWindow * window)
|
||||
{
|
||||
GstGLWindowWin32Class *window_class;
|
||||
GstGLWindowWin32Private *priv;
|
||||
GstGLWindowWin32 *window_win32;
|
||||
|
||||
window_win32 = GST_GL_WINDOW_WIN32 (window);
|
||||
window_class = GST_GL_WINDOW_WIN32_GET_CLASS (window_win32);
|
||||
priv = window_win32->priv;
|
||||
|
||||
priv->activate_result = window_class->activate (window_win32, priv->activate);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_gl_window_win32_activate (GstGLWindow * window, gboolean activate)
|
||||
{
|
||||
GstGLWindowWin32 *window_win32;
|
||||
GstGLWindowWin32Private *priv;
|
||||
|
||||
window_win32 = GST_GL_WINDOW_WIN32 (window);
|
||||
priv = window_win32->priv;
|
||||
priv->activate = activate;
|
||||
|
||||
gst_gl_window_win32_send_message (window,
|
||||
GST_GL_WINDOW_CB (callback_activate), window_win32);
|
||||
|
||||
return priv->activate_result;
|
||||
}
|
||||
|
||||
void
|
||||
gst_gl_window_win32_set_window_handle (GstGLWindow * window, guintptr id)
|
||||
{
|
||||
GstGLWindowWin32 *window_win32;
|
||||
|
@ -284,7 +216,7 @@ gst_gl_window_win32_set_window_handle (GstGLWindow * window, guintptr id)
|
|||
if (parent_id) {
|
||||
WNDPROC parent_proc = GetProp (parent_id, "gl_window_parent_proc");
|
||||
|
||||
GST_DEBUG ("release parent %" G_GUINTPTR_FORMAT "\n", (guintptr) parent_id);
|
||||
GST_DEBUG ("release parent %" G_GUINTPTR_FORMAT, (guintptr) parent_id);
|
||||
|
||||
g_return_if_fail (parent_proc);
|
||||
|
||||
|
@ -299,7 +231,7 @@ gst_gl_window_win32_set_window_handle (GstGLWindow * window, guintptr id)
|
|||
(WNDPROC) GetWindowLongPtr ((HWND) id, GWLP_WNDPROC);
|
||||
RECT rect;
|
||||
|
||||
GST_DEBUG ("set parent %" G_GUINTPTR_FORMAT "\n", id);
|
||||
GST_DEBUG ("set parent %" G_GUINTPTR_FORMAT, id);
|
||||
|
||||
SetProp ((HWND) id, "gl_window_id", window_win32->internal_win_id);
|
||||
SetProp ((HWND) id, "gl_window_parent_proc", (WNDPROC) window_parent_proc);
|
||||
|
@ -326,7 +258,7 @@ gst_gl_window_win32_set_window_handle (GstGLWindow * window, guintptr id)
|
|||
}
|
||||
|
||||
/* Thread safe */
|
||||
void
|
||||
static void
|
||||
gst_gl_window_win32_draw (GstGLWindow * window, guint width, guint height)
|
||||
{
|
||||
GstGLWindowWin32 *window_win32 = GST_GL_WINDOW_WIN32 (window);
|
||||
|
@ -355,20 +287,21 @@ gst_gl_window_win32_draw (GstGLWindow * window, guint width, guint height)
|
|||
RDW_NOERASE | RDW_INTERNALPAINT | RDW_INVALIDATE);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
gst_gl_window_win32_run (GstGLWindow * window)
|
||||
{
|
||||
gint bRet;
|
||||
MSG msg;
|
||||
|
||||
GST_INFO ("begin message loop\n");
|
||||
GST_INFO ("begin message loop");
|
||||
|
||||
while (TRUE) {
|
||||
bRet = GetMessage (&msg, NULL, 0, 0);
|
||||
if (bRet == 0)
|
||||
break;
|
||||
else if (bRet == -1) {
|
||||
GST_WARNING ("Failed to get message %lud\n", GetLastError ());
|
||||
GST_WARNING ("Failed to get message 0x%x",
|
||||
(unsigned int) GetLastError ());
|
||||
break;
|
||||
} else {
|
||||
GST_TRACE ("handle message");
|
||||
|
@ -377,11 +310,11 @@ gst_gl_window_win32_run (GstGLWindow * window)
|
|||
}
|
||||
}
|
||||
|
||||
GST_INFO ("end message loop\n");
|
||||
GST_INFO ("end message loop");
|
||||
}
|
||||
|
||||
/* Thread safe */
|
||||
void
|
||||
static void
|
||||
gst_gl_window_win32_quit (GstGLWindow * window)
|
||||
{
|
||||
GstGLWindowWin32 *window_win32;
|
||||
|
@ -398,7 +331,7 @@ gst_gl_window_win32_quit (GstGLWindow * window)
|
|||
}
|
||||
|
||||
/* Thread safe */
|
||||
void
|
||||
static void
|
||||
gst_gl_window_win32_send_message (GstGLWindow * window, GstGLWindowCB callback,
|
||||
gpointer data)
|
||||
{
|
||||
|
@ -420,73 +353,33 @@ LRESULT CALLBACK
|
|||
window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
GstGLWindowWin32 *window_win32;
|
||||
GstGLWindowWin32Class *window_class;
|
||||
GstGLWindowWin32Private *priv;
|
||||
|
||||
if (uMsg == WM_CREATE) {
|
||||
window_win32 =
|
||||
GST_GL_WINDOW_WIN32 (((LPCREATESTRUCT) lParam)->lpCreateParams);
|
||||
window_class = GST_GL_WINDOW_WIN32_GET_CLASS (window_win32);
|
||||
|
||||
GST_DEBUG ("WM_CREATE\n");
|
||||
GST_TRACE ("WM_CREATE");
|
||||
|
||||
{
|
||||
priv = window_win32->priv;
|
||||
window_win32->device = GetDC (hWnd);
|
||||
|
||||
window_class->choose_format (window_win32);
|
||||
|
||||
window_class->create_context (window_win32, priv->gl_api,
|
||||
priv->external_gl_context, priv->error);
|
||||
|
||||
/* priv->gl_context = wglCreateContext (priv->device);
|
||||
if (priv->gl_context)
|
||||
GST_DEBUG ("gl context created: %" G_GUINTPTR_FORMAT "\n",
|
||||
(guintptr) priv->gl_context);
|
||||
else
|
||||
GST_DEBUG ("failed to create glcontext %" G_GUINTPTR_FORMAT ", %lud\n",
|
||||
(guintptr) hWnd, GetLastError ());
|
||||
g_assert (priv->gl_context);*/
|
||||
ReleaseDC (hWnd, window_win32->device);
|
||||
|
||||
window_class->activate (window_win32, TRUE);
|
||||
|
||||
/* if (!wglMakeCurrent (priv->device, priv->gl_context))
|
||||
GST_DEBUG ("failed to make opengl context current %" G_GUINTPTR_FORMAT
|
||||
", %lud\n", (guintptr) hWnd, GetLastError ());
|
||||
*/
|
||||
if (priv->external_gl_context)
|
||||
window_class->share_context (window_win32, priv->external_gl_context);
|
||||
/*
|
||||
if (priv->external_gl_context) {
|
||||
if (!wglShareLists (priv->external_gl_context, priv->gl_context))
|
||||
GST_DEBUG ("failed to share opengl context %" G_GUINTPTR_FORMAT
|
||||
" with %" G_GUINTPTR_FORMAT "\n", (guintptr) priv->gl_context,
|
||||
(guintptr) priv->external_gl_context);
|
||||
else
|
||||
GST_DEBUG ("share opengl context succeed %" G_GUINTPTR_FORMAT "\n",
|
||||
(guintptr) priv->external_gl_context);
|
||||
}*/
|
||||
}
|
||||
window_win32->device = GetDC (hWnd);
|
||||
/* Do this, otherwise we hang on exit. We can still use it (due to the
|
||||
* CS_OWNDC flag in the WindowClass) after we have Released.
|
||||
*/
|
||||
ReleaseDC (hWnd, window_win32->device);
|
||||
|
||||
SetProp (hWnd, "gl_window", window_win32);
|
||||
|
||||
return 0;
|
||||
} else if (GetProp (hWnd, "gl_window")) {
|
||||
GstGLWindow *window;
|
||||
GstGLContext *context;
|
||||
GstGLContextClass *context_class;
|
||||
|
||||
window_win32 = GST_GL_WINDOW_WIN32 (GetProp (hWnd, "gl_window"));
|
||||
window_class = GST_GL_WINDOW_WIN32_GET_CLASS (window_win32);
|
||||
window = GST_GL_WINDOW (window_win32);
|
||||
priv = window_win32->priv;
|
||||
context = gst_gl_window_get_context (window);
|
||||
context_class = GST_GL_CONTEXT_GET_CLASS (context);
|
||||
|
||||
g_assert (window_win32->internal_win_id == hWnd);
|
||||
|
||||
/* g_assert (!wglGetCurrentContext ()
|
||||
|| priv->gl_context == wglGetCurrentContext ());
|
||||
*/
|
||||
switch (uMsg) {
|
||||
|
||||
case WM_SIZE:
|
||||
{
|
||||
if (window->resize) {
|
||||
|
@ -495,36 +388,32 @@ window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_PAINT:
|
||||
{
|
||||
if (window->draw) {
|
||||
PAINTSTRUCT ps;
|
||||
BeginPaint (hWnd, &ps);
|
||||
window->draw (window->draw_data);
|
||||
window_class->swap_buffers (window_win32);
|
||||
// SwapBuffers (priv->device);
|
||||
context_class->swap_buffers (context);
|
||||
EndPaint (hWnd, &ps);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_CLOSE:
|
||||
{
|
||||
ShowWindowAsync (window_win32->internal_win_id, SW_HIDE);
|
||||
|
||||
GST_DEBUG ("WM_CLOSE\n");
|
||||
GST_TRACE ("WM_CLOSE");
|
||||
|
||||
if (window->close)
|
||||
window->close (window->close_data);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_GST_GL_WINDOW_QUIT:
|
||||
{
|
||||
HWND parent_id = 0;
|
||||
|
||||
GST_DEBUG ("WM_GST_GL_WINDOW_QUIT\n");
|
||||
GST_TRACE ("WM_GST_GL_WINDOW_QUIT");
|
||||
|
||||
parent_id = window_win32->parent_win_id;
|
||||
if (parent_id) {
|
||||
|
@ -541,38 +430,22 @@ window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|||
window_win32->is_closed = TRUE;
|
||||
RemoveProp (hWnd, "gl_window");
|
||||
|
||||
window_class->activate (window_win32, FALSE);
|
||||
|
||||
window_class->destroy_context (window_win32);
|
||||
|
||||
/* if (!wglMakeCurrent (NULL, NULL))
|
||||
GST_DEBUG ("failed to make current %" G_GUINTPTR_FORMAT ", %lud\n",
|
||||
(guintptr) hWnd, GetLastError ());
|
||||
|
||||
if (priv->gl_context) {
|
||||
if (!wglDeleteContext (priv->gl_context))
|
||||
GST_DEBUG ("failed to destroy context %" G_GUINTPTR_FORMAT ", %lud\n",
|
||||
(guintptr) priv->gl_context, GetLastError ());
|
||||
}
|
||||
*/
|
||||
if (window_win32->internal_win_id) {
|
||||
if (!DestroyWindow (window_win32->internal_win_id))
|
||||
GST_DEBUG ("failed to destroy window %" G_GUINTPTR_FORMAT
|
||||
", %lud\n", (guintptr) hWnd, GetLastError ());
|
||||
GST_WARNING ("failed to destroy window %" G_GUINTPTR_FORMAT
|
||||
", 0x%x", (guintptr) hWnd, (unsigned int) GetLastError ());
|
||||
}
|
||||
|
||||
PostQuitMessage (0);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_CAPTURECHANGED:
|
||||
{
|
||||
GST_DEBUG ("WM_CAPTURECHANGED\n");
|
||||
GST_DEBUG ("WM_CAPTURECHANGED");
|
||||
if (window->draw)
|
||||
window->draw (window->draw_data);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_GST_GL_WINDOW_CUSTOM:
|
||||
{
|
||||
if (!window_win32->is_closed) {
|
||||
|
@ -581,10 +454,8 @@ window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_ERASEBKGND:
|
||||
return TRUE;
|
||||
|
||||
default:
|
||||
{
|
||||
/* transmit messages to the parrent (ex: mouse/keyboard input) */
|
||||
|
@ -595,9 +466,12 @@ window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|||
}
|
||||
}
|
||||
|
||||
gst_object_unref (context);
|
||||
|
||||
return 0;
|
||||
} else
|
||||
} else {
|
||||
return DefWindowProc (hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT FAR PASCAL
|
||||
|
|
|
@ -77,6 +77,8 @@ GType gst_gl_window_win32_get_type (void);
|
|||
|
||||
GstGLWindowWin32 * gst_gl_window_win32_new (void);
|
||||
|
||||
gboolean gst_gl_window_win32_create_window (GstGLWindowWin32 * window_win32, GError ** error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_GL_WINDOW_WIN32_H__ */
|
||||
|
|
|
@ -1,229 +0,0 @@
|
|||
/*
|
||||
* GStreamer
|
||||
* Copyright (C) 2008 Julien Isorce <julien.isorce@gmail.com>
|
||||
* Copyright (C) 2012 Matthew Waters <ystreet00@gmail.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.
|
||||
*/
|
||||
|
||||
#define GLIB_DISABLE_DEPRECATION_WARNINGS
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "../gstgl_fwd.h"
|
||||
#include <gst/gl/gstglcontext.h>
|
||||
|
||||
#include "gstglwindow_win32_wgl.h"
|
||||
|
||||
#define GST_CAT_DEFAULT gst_gl_window_debug
|
||||
|
||||
#define gst_gl_window_win32_wgl_parent_class parent_class
|
||||
G_DEFINE_TYPE (GstGLWindowWin32WGL, gst_gl_window_win32_wgl,
|
||||
GST_GL_TYPE_WINDOW_WIN32);
|
||||
|
||||
static guintptr gst_gl_window_win32_wgl_get_gl_context (GstGLWindowWin32 *
|
||||
window_win32);
|
||||
static void gst_gl_window_win32_wgl_swap_buffers (GstGLWindowWin32 *
|
||||
window_win32);
|
||||
static gboolean gst_gl_window_win32_wgl_choose_format (GstGLWindowWin32 *
|
||||
window_win32);
|
||||
static gboolean gst_gl_window_win32_wgl_activate (GstGLWindowWin32 *
|
||||
window_win32, gboolean activate);
|
||||
static gboolean gst_gl_window_win32_wgl_create_context (GstGLWindowWin32 *
|
||||
window_win32, GstGLAPI gl_api, guintptr external_gl_context,
|
||||
GError ** error);
|
||||
static void gst_gl_window_win32_wgl_destroy_context (GstGLWindowWin32 *
|
||||
window_win32);
|
||||
GstGLAPI gst_gl_window_win32_wgl_get_gl_api (GstGLWindow * window);
|
||||
static gpointer gst_gl_window_win32_wgl_get_proc_address (GstGLWindow * window,
|
||||
const gchar * name);
|
||||
|
||||
static void
|
||||
gst_gl_window_win32_wgl_class_init (GstGLWindowWin32WGLClass * klass)
|
||||
{
|
||||
GstGLWindowClass *window_class = (GstGLWindowClass *) klass;
|
||||
GstGLWindowWin32Class *window_win32_class = (GstGLWindowWin32Class *) klass;
|
||||
|
||||
window_win32_class->get_gl_context =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_win32_wgl_get_gl_context);
|
||||
window_win32_class->choose_format =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_win32_wgl_choose_format);
|
||||
window_win32_class->activate =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_win32_wgl_activate);
|
||||
window_win32_class->create_context =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_win32_wgl_create_context);
|
||||
window_win32_class->destroy_context =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_win32_wgl_destroy_context);
|
||||
window_win32_class->swap_buffers =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_win32_wgl_swap_buffers);
|
||||
|
||||
window_class->get_proc_address =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_win32_wgl_get_proc_address);
|
||||
window_class->get_gl_api =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_win32_wgl_get_gl_api);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_window_win32_wgl_init (GstGLWindowWin32WGL * window)
|
||||
{
|
||||
}
|
||||
|
||||
/* Must be called in the gl thread */
|
||||
GstGLWindowWin32WGL *
|
||||
gst_gl_window_win32_wgl_new (void)
|
||||
{
|
||||
GstGLWindowWin32WGL *window =
|
||||
g_object_new (GST_GL_TYPE_WINDOW_WIN32_WGL, NULL);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_gl_window_win32_wgl_create_context (GstGLWindowWin32 * window_win32,
|
||||
GstGLAPI gl_api, guintptr external_gl_context, GError ** error)
|
||||
{
|
||||
GstGLWindowWin32WGL *window_wgl;
|
||||
|
||||
window_wgl = GST_GL_WINDOW_WIN32_WGL (window_win32);
|
||||
|
||||
window_wgl->wgl_context = wglCreateContext (window_win32->device);
|
||||
if (window_wgl->wgl_context)
|
||||
GST_DEBUG ("gl context created: %" G_GUINTPTR_FORMAT,
|
||||
(guintptr) window_wgl->wgl_context);
|
||||
else {
|
||||
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_CREATE_CONTEXT,
|
||||
"failed to create glcontext:%lu", GetLastError ());
|
||||
goto failure;
|
||||
}
|
||||
g_assert (window_wgl->wgl_context);
|
||||
|
||||
GST_LOG ("gl context id: %" G_GUINTPTR_FORMAT,
|
||||
(guintptr) window_wgl->wgl_context);
|
||||
|
||||
return TRUE;
|
||||
|
||||
failure:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_window_win32_wgl_destroy_context (GstGLWindowWin32 * window_win32)
|
||||
{
|
||||
GstGLWindowWin32WGL *window_wgl;
|
||||
|
||||
window_wgl = GST_GL_WINDOW_WIN32_WGL (window_win32);
|
||||
|
||||
if (window_wgl->wgl_context)
|
||||
wglDeleteContext (window_wgl->wgl_context);
|
||||
window_wgl->wgl_context = NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_gl_window_win32_wgl_choose_format (GstGLWindowWin32 * window_win32)
|
||||
{
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
gint pixelformat = 0;
|
||||
gboolean res = FALSE;
|
||||
|
||||
pfd.nSize = sizeof (PIXELFORMATDESCRIPTOR);
|
||||
pfd.nVersion = 1;
|
||||
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
|
||||
pfd.iPixelType = PFD_TYPE_RGBA;
|
||||
pfd.cColorBits = 24;
|
||||
pfd.cRedBits = 8;
|
||||
pfd.cRedShift = 0;
|
||||
pfd.cGreenBits = 8;
|
||||
pfd.cGreenShift = 0;
|
||||
pfd.cBlueBits = 8;
|
||||
pfd.cBlueShift = 0;
|
||||
pfd.cAlphaBits = 0;
|
||||
pfd.cAlphaShift = 0;
|
||||
pfd.cAccumBits = 0;
|
||||
pfd.cAccumRedBits = 0;
|
||||
pfd.cAccumGreenBits = 0;
|
||||
pfd.cAccumBlueBits = 0;
|
||||
pfd.cAccumAlphaBits = 0;
|
||||
pfd.cDepthBits = 24;
|
||||
pfd.cStencilBits = 8;
|
||||
pfd.cAuxBuffers = 0;
|
||||
pfd.iLayerType = PFD_MAIN_PLANE;
|
||||
pfd.bReserved = 0;
|
||||
pfd.dwLayerMask = 0;
|
||||
pfd.dwVisibleMask = 0;
|
||||
pfd.dwDamageMask = 0;
|
||||
|
||||
pfd.cColorBits = (BYTE) GetDeviceCaps (window_win32->device, BITSPIXEL);
|
||||
|
||||
pixelformat = ChoosePixelFormat (window_win32->device, &pfd);
|
||||
|
||||
g_return_val_if_fail (pixelformat, FALSE);
|
||||
|
||||
res = SetPixelFormat (window_win32->device, pixelformat, &pfd);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_window_win32_wgl_swap_buffers (GstGLWindowWin32 * window_win32)
|
||||
{
|
||||
SwapBuffers (window_win32->device);
|
||||
}
|
||||
|
||||
static guintptr
|
||||
gst_gl_window_win32_wgl_get_gl_context (GstGLWindowWin32 * window_win32)
|
||||
{
|
||||
return (guintptr) GST_GL_WINDOW_WIN32_WGL (window_win32)->wgl_context;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_gl_window_win32_wgl_activate (GstGLWindowWin32 * window_win32,
|
||||
gboolean activate)
|
||||
{
|
||||
gboolean result;
|
||||
|
||||
if (activate) {
|
||||
result = wglMakeCurrent (window_win32->device,
|
||||
GST_GL_WINDOW_WIN32_WGL (window_win32)->wgl_context);
|
||||
} else {
|
||||
result = wglMakeCurrent (NULL, NULL);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
GstGLAPI
|
||||
gst_gl_window_win32_wgl_get_gl_api (GstGLWindow * window)
|
||||
{
|
||||
return GST_GL_API_OPENGL;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
gst_gl_window_win32_wgl_get_proc_address (GstGLWindow * window,
|
||||
const gchar * name)
|
||||
{
|
||||
GstGLContext *context;
|
||||
gpointer result;
|
||||
|
||||
if (!(result = wglGetProcAddress ((LPCSTR) name))) {
|
||||
result = gst_gl_context_default_get_proc_address (context, name);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
* GStreamer
|
||||
* Copyright (C) 2012 Matthew Waters <ystreet00@gmail.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 __GST_GL_WINDOW_WIN32_WGL_H__
|
||||
#define __GST_GL_WINDOW_WIN32_WGL_H__
|
||||
|
||||
#include "gstglwindow_win32.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_GL_TYPE_WINDOW_WIN32_WGL (gst_gl_window_win32_wgl_get_type())
|
||||
#define GST_GL_WINDOW_WIN32_WGL(o) (G_TYPE_CHECK_INSTANCE_CAST((o), GST_GL_TYPE_WINDOW_WIN32_WGL, GstGLWindowWin32WGL))
|
||||
#define GST_GL_WINDOW_WIN32_WGL_CLASS(k) (G_TYPE_CHECK_CLASS((k), GST_GL_TYPE_WINDOW_WIN32_WGL, GstGLWindowWin32WGLClass))
|
||||
#define GST_GL_IS_WINDOW_WIN32_WGL(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), GST_GL_TYPE_WINDOW_WIN32_WGL))
|
||||
#define GST_GL_IS_WINDOW_WIN32_WGL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), GST_GL_TYPE_WINDOW_WIN32_WGL))
|
||||
#define GST_GL_WINDOW_WIN32_WGL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_GL_TYPE_WINDOW_WIN32_WGL, GstGLWindowWin32WGLClass))
|
||||
|
||||
typedef struct _GstGLWindowWin32WGL GstGLWindowWin32WGL;
|
||||
typedef struct _GstGLWindowWin32WGLClass GstGLWindowWin32WGLClass;
|
||||
|
||||
struct _GstGLWindowWin32WGL {
|
||||
/*< private >*/
|
||||
GstGLWindowWin32 parent;
|
||||
|
||||
HGLRC wgl_context;
|
||||
HGLRC external_gl_context;
|
||||
|
||||
gpointer _reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
struct _GstGLWindowWin32WGLClass {
|
||||
/*< private >*/
|
||||
GstGLWindowWin32Class parent_class;
|
||||
|
||||
/*< private >*/
|
||||
gpointer _reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
GType gst_gl_window_win32_wgl_get_type (void);
|
||||
|
||||
GstGLWindowWin32WGL * gst_gl_window_win32_wgl_new (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_GL_WINDOW_X11_H__ */
|
|
@ -11,14 +11,15 @@ noinst_HEADERS = \
|
|||
x11_event_source.h
|
||||
|
||||
if USE_GLX
|
||||
libgstgl_x11_la_SOURCES += gstglwindow_x11_glx.c
|
||||
noinst_HEADERS += gstglwindow_x11_glx.h
|
||||
endif
|
||||
if USE_EGL
|
||||
libgstgl_x11_la_SOURCES += gstglwindow_x11_egl.c
|
||||
noinst_HEADERS += gstglwindow_x11_egl.h
|
||||
libgstgl_x11_la_SOURCES += gstglcontext_glx.c
|
||||
noinst_HEADERS += gstglcontext_glx.h
|
||||
endif
|
||||
|
||||
#if USE_EGL
|
||||
#libgstgl_x11_la_SOURCES += gstglwindow_x11_egl.c
|
||||
#noinst_HEADERS += gstglwindow_x11_egl.h
|
||||
#endif
|
||||
|
||||
libgstgl_x11_la_CFLAGS = \
|
||||
-I$(top_srcdir)/gst-libs \
|
||||
$(GL_CFLAGS) \
|
||||
|
|
396
gst-libs/gst/gl/x11/gstglcontext_glx.c
Normal file
396
gst-libs/gst/gl/x11/gstglcontext_glx.c
Normal file
|
@ -0,0 +1,396 @@
|
|||
/*
|
||||
* GStreamer
|
||||
* Copyright (C) 2008 Julien Isorce <julien.isorce@gmail.com>
|
||||
* Copyright (C) 2012 Matthew Waters <ystreet00@gmail.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.
|
||||
*/
|
||||
|
||||
#define GLIB_DISABLE_DEPRECATION_WARNINGS
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "../gstgl_fwd.h"
|
||||
#include <gst/gl/gstglcontext.h>
|
||||
|
||||
#include <gst/gl/gl.h>
|
||||
#include "gstglcontext_glx.h"
|
||||
|
||||
#define GST_CAT_DEFAULT gst_gl_window_debug
|
||||
|
||||
#define gst_gl_context_glx_parent_class parent_class
|
||||
G_DEFINE_TYPE (GstGLContextGLX, gst_gl_context_glx, GST_GL_TYPE_CONTEXT);
|
||||
|
||||
#define GST_GL_CONTEXT_GLX_GET_PRIVATE(o) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE((o), GST_GL_TYPE_CONTEXT_GLX, GstGLContextGLXPrivate))
|
||||
|
||||
static guintptr gst_gl_context_glx_get_gl_context (GstGLContext * context);
|
||||
static void gst_gl_context_glx_swap_buffers (GstGLContext * context);
|
||||
static gboolean gst_gl_context_glx_activate (GstGLContext * context,
|
||||
gboolean activate);
|
||||
static gboolean gst_gl_context_glx_create_context (GstGLContext *
|
||||
context, GstGLAPI gl_api, guintptr external_gl_context, GError ** error);
|
||||
static void gst_gl_context_glx_destroy_context (GstGLContext * context);
|
||||
static gboolean gst_gl_context_glx_choose_format (GstGLContext *
|
||||
context, GError ** error);
|
||||
GstGLAPI gst_gl_context_glx_get_gl_api (GstGLContext * context);
|
||||
static gpointer gst_gl_context_glx_get_proc_address (GstGLContext * context,
|
||||
const gchar * name);
|
||||
|
||||
struct _GstGLContextGLXPrivate
|
||||
{
|
||||
int glx_major;
|
||||
int glx_minor;
|
||||
|
||||
GstGLAPI context_api;
|
||||
|
||||
GLXFBConfig *fbconfigs;
|
||||
GLXContext (*glXCreateContextAttribsARB) (Display *, GLXFBConfig,
|
||||
GLXContext, Bool, const int *);
|
||||
};
|
||||
|
||||
static void
|
||||
gst_gl_context_glx_class_init (GstGLContextGLXClass * klass)
|
||||
{
|
||||
GstGLContextClass *context_class = (GstGLContextClass *) klass;
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GstGLContextGLXPrivate));
|
||||
|
||||
context_class->get_gl_context =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_context_glx_get_gl_context);
|
||||
context_class->activate = GST_DEBUG_FUNCPTR (gst_gl_context_glx_activate);
|
||||
context_class->create_context =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_context_glx_create_context);
|
||||
context_class->destroy_context =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_context_glx_destroy_context);
|
||||
context_class->choose_format =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_context_glx_choose_format);
|
||||
context_class->swap_buffers =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_context_glx_swap_buffers);
|
||||
|
||||
context_class->get_gl_api = GST_DEBUG_FUNCPTR (gst_gl_context_glx_get_gl_api);
|
||||
context_class->get_proc_address =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_context_glx_get_proc_address);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_context_glx_init (GstGLContextGLX * context)
|
||||
{
|
||||
context->priv = GST_GL_CONTEXT_GLX_GET_PRIVATE (context);
|
||||
}
|
||||
|
||||
GstGLContextGLX *
|
||||
gst_gl_context_glx_new (void)
|
||||
{
|
||||
GstGLContextGLX *window = g_object_new (GST_GL_TYPE_CONTEXT_GLX, NULL);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_describe_fbconfig (Display * display, GLXFBConfig config)
|
||||
{
|
||||
int val;
|
||||
|
||||
glXGetFBConfigAttrib (display, config, GLX_FBCONFIG_ID, &val);
|
||||
GST_DEBUG ("ID: %d", val);
|
||||
glXGetFBConfigAttrib (display, config, GLX_DOUBLEBUFFER, &val);
|
||||
GST_DEBUG ("double buffering: %d", val);
|
||||
glXGetFBConfigAttrib (display, config, GLX_RED_SIZE, &val);
|
||||
GST_DEBUG ("red: %d", val);
|
||||
glXGetFBConfigAttrib (display, config, GLX_GREEN_SIZE, &val);
|
||||
GST_DEBUG ("green: %d", val);
|
||||
glXGetFBConfigAttrib (display, config, GLX_BLUE_SIZE, &val);
|
||||
GST_DEBUG ("blue: %d", val);
|
||||
glXGetFBConfigAttrib (display, config, GLX_ALPHA_SIZE, &val);
|
||||
GST_DEBUG ("alpha: %d", val);
|
||||
glXGetFBConfigAttrib (display, config, GLX_DEPTH_SIZE, &val);
|
||||
GST_DEBUG ("depth: %d", val);
|
||||
glXGetFBConfigAttrib (display, config, GLX_STENCIL_SIZE, &val);
|
||||
GST_DEBUG ("stencil: %d", val);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_gl_context_glx_create_context (GstGLContext * context,
|
||||
GstGLAPI gl_api, guintptr external_gl_context, GError ** error)
|
||||
{
|
||||
GstGLContextGLX *context_glx;
|
||||
GstGLWindow *window;
|
||||
GstGLWindowX11 *window_x11;
|
||||
gboolean create_context;
|
||||
const char *glx_exts;
|
||||
int x_error;
|
||||
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_window_get_display (window);
|
||||
|
||||
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,
|
||||
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_OPENGL3 | 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_WINDOW_ERROR, GST_GL_WINDOW_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);
|
||||
|
||||
return TRUE;
|
||||
|
||||
failure:
|
||||
if (window)
|
||||
gst_object_unref (window);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_context_glx_destroy_context (GstGLContext * context)
|
||||
{
|
||||
GstGLWindow *window;
|
||||
GstGLContextGLX *context_glx;
|
||||
Display *device;
|
||||
|
||||
context_glx = GST_GL_CONTEXT_GLX (context);
|
||||
window = gst_gl_context_get_window (context);
|
||||
device = (Display *) gst_gl_window_get_display (window);
|
||||
|
||||
glXDestroyContext (device, context_glx->glx_context);
|
||||
|
||||
context_glx->glx_context = 0;
|
||||
|
||||
gst_object_unref (window);
|
||||
}
|
||||
|
||||
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_window_get_display (window);
|
||||
|
||||
if (!glXQueryExtension (device, &error_base, &event_base)) {
|
||||
g_set_error (error, GST_GL_WINDOW_ERROR,
|
||||
GST_GL_WINDOW_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_WINDOW_ERROR, GST_GL_WINDOW_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_WINDOW_ERROR, GST_GL_WINDOW_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_WINDOW_ERROR, GST_GL_WINDOW_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_WINDOW_ERROR, GST_GL_WINDOW_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 void
|
||||
gst_gl_context_glx_swap_buffers (GstGLContext * context)
|
||||
{
|
||||
GstGLWindow *window = gst_gl_context_get_window (context);
|
||||
Display *device = (Display *) gst_gl_window_get_display (window);
|
||||
Window window_handle = (Window) gst_gl_window_get_window_handle (window);
|
||||
|
||||
glXSwapBuffers (device, window_handle);
|
||||
|
||||
gst_object_unref (window);
|
||||
}
|
||||
|
||||
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_activate (GstGLContext * context, gboolean activate)
|
||||
{
|
||||
GstGLWindow *window = gst_gl_context_get_window (context);
|
||||
Display *device = (Display *) gst_gl_window_get_display (window);
|
||||
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;
|
||||
}
|
||||
|
||||
GstGLAPI
|
||||
gst_gl_context_glx_get_gl_api (GstGLContext * context)
|
||||
{
|
||||
GstGLContextGLX *context_glx;
|
||||
|
||||
context_glx = GST_GL_CONTEXT_GLX (context);
|
||||
|
||||
return context_glx->priv->context_api;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
gst_gl_context_glx_get_proc_address (GstGLContext * context, const gchar * name)
|
||||
{
|
||||
gpointer result;
|
||||
|
||||
if (!(result = glXGetProcAddressARB ((const GLubyte *) name))) {
|
||||
result = gst_gl_context_default_get_proc_address (context, name);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
66
gst-libs/gst/gl/x11/gstglcontext_glx.h
Normal file
66
gst-libs/gst/gl/x11/gstglcontext_glx.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* GStreamer
|
||||
* Copyright (C) 2012 Matthew Waters <ystreet00@gmail.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 __GST_GL_CONTEXT_GLX_H__
|
||||
#define __GST_GL_CONTEXT_GLX_H__
|
||||
|
||||
#include "gstglwindow_x11.h"
|
||||
|
||||
#include <GL/glx.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_GL_TYPE_CONTEXT_GLX (gst_gl_context_glx_get_type())
|
||||
#define GST_GL_CONTEXT_GLX(o) (G_TYPE_CHECK_INSTANCE_CAST((o), GST_GL_TYPE_CONTEXT_GLX, GstGLContextGLX))
|
||||
#define GST_GL_CONTEXT_GLX_CLASS(k) (G_TYPE_CHECK_CLASS((k), GST_GL_TYPE_CONTEXT_GLX, GstGLContextGLXClass))
|
||||
#define GST_GL_IS_CONTEXT_GLX(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), GST_GL_TYPE_CONTEXT_GLX))
|
||||
#define GST_GL_IS_CONTEXT_GLX_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), GST_GL_TYPE_CONTEXT_GLX))
|
||||
#define GST_GL_CONTEXT_GLX_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_GL_TYPE_CONTEXT_GLX, GstGLContextGLX_Class))
|
||||
|
||||
typedef struct _GstGLContextGLX GstGLContextGLX;
|
||||
typedef struct _GstGLContextGLXClass GstGLContextGLXClass;
|
||||
typedef struct _GstGLContextGLXPrivate GstGLContextGLXPrivate;
|
||||
|
||||
struct _GstGLContextGLX {
|
||||
/*< private >*/
|
||||
GstGLContext parent;
|
||||
|
||||
GLXContext glx_context;
|
||||
|
||||
GstGLContextGLXPrivate *priv;
|
||||
|
||||
gpointer _reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
struct _GstGLContextGLXClass {
|
||||
/*< private >*/
|
||||
GstGLContextClass parent_class;
|
||||
|
||||
/*< private >*/
|
||||
gpointer _reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
GType gst_gl_context_glx_get_type (void);
|
||||
|
||||
GstGLContextGLX * gst_gl_context_glx_new (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_GL_CONTEXT_H__ */
|
|
@ -31,20 +31,13 @@
|
|||
#include "x11_event_source.h"
|
||||
#include "gstglwindow_x11.h"
|
||||
|
||||
#if GST_GL_HAVE_PLATFORM_GLX
|
||||
# include "gstglwindow_x11_glx.h"
|
||||
#endif
|
||||
#if GST_GL_HAVE_PLATFORM_EGL
|
||||
# include "gstglwindow_x11_egl.h"
|
||||
#endif
|
||||
|
||||
#define GST_GL_WINDOW_X11_GET_PRIVATE(o) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE((o), GST_GL_TYPE_WINDOW_X11, GstGLWindowX11Private))
|
||||
|
||||
#define GST_CAT_DEFAULT gst_gl_window_debug
|
||||
|
||||
#define gst_gl_window_x11_parent_class parent_class
|
||||
G_DEFINE_ABSTRACT_TYPE (GstGLWindowX11, gst_gl_window_x11, GST_GL_TYPE_WINDOW);
|
||||
G_DEFINE_TYPE (GstGLWindowX11, gst_gl_window_x11, GST_GL_TYPE_WINDOW);
|
||||
|
||||
/* X error trap */
|
||||
static int TrappedErrorCode = 0;
|
||||
|
@ -62,10 +55,12 @@ struct _GstGLWindowX11Private
|
|||
gboolean activate_result;
|
||||
};
|
||||
|
||||
guintptr gst_gl_window_x11_get_display (GstGLWindow * window);
|
||||
guintptr gst_gl_window_x11_get_gl_context (GstGLWindow * window);
|
||||
gboolean gst_gl_window_x11_activate (GstGLWindow * window, gboolean activate);
|
||||
void gst_gl_window_x11_set_window_handle (GstGLWindow * window,
|
||||
guintptr handle);
|
||||
guintptr gst_gl_window_x11_get_window_handle (GstGLWindow * window);
|
||||
void gst_gl_window_x11_draw_unlocked (GstGLWindow * window, guint width,
|
||||
guint height);
|
||||
void gst_gl_window_x11_draw (GstGLWindow * window, guint width, guint height);
|
||||
|
@ -78,8 +73,6 @@ gboolean gst_gl_window_x11_create_context (GstGLWindow * window,
|
|||
gboolean gst_gl_window_x11_open (GstGLWindow * window, GError ** error);
|
||||
void gst_gl_window_x11_close (GstGLWindow * window);
|
||||
|
||||
static gboolean gst_gl_window_x11_create_window (GstGLWindowX11 * window_x11);
|
||||
|
||||
static void
|
||||
gst_gl_window_x11_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
|
@ -150,13 +143,11 @@ gst_gl_window_x11_class_init (GstGLWindowX11Class * klass)
|
|||
g_param_spec_string ("display", "Display", "X Display name", NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
window_class->create_context =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_x11_create_context);
|
||||
window_class->get_gl_context =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_x11_get_gl_context);
|
||||
window_class->activate = GST_DEBUG_FUNCPTR (gst_gl_window_x11_activate);
|
||||
window_class->get_display = GST_DEBUG_FUNCPTR (gst_gl_window_x11_get_display);
|
||||
window_class->set_window_handle =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_x11_set_window_handle);
|
||||
window_class->get_window_handle =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_x11_get_window_handle);
|
||||
window_class->draw_unlocked =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_x11_draw_unlocked);
|
||||
window_class->draw = GST_DEBUG_FUNCPTR (gst_gl_window_x11_draw);
|
||||
|
@ -181,26 +172,10 @@ GstGLWindowX11 *
|
|||
gst_gl_window_x11_new (void)
|
||||
{
|
||||
GstGLWindowX11 *window = NULL;
|
||||
const gchar *user_choice;
|
||||
|
||||
user_choice = g_getenv ("GST_GL_PLATFORM");
|
||||
window = g_object_new (GST_GL_TYPE_WINDOW_X11, NULL);
|
||||
|
||||
GST_INFO ("Attempting to create x11 window, user platform choice:%s",
|
||||
user_choice ? user_choice : "(null)");
|
||||
|
||||
#if GST_GL_HAVE_PLATFORM_GLX
|
||||
if (!window && (!user_choice || g_strstr_len (user_choice, 3, "glx") != NULL))
|
||||
window = GST_GL_WINDOW_X11 (gst_gl_window_x11_glx_new ());
|
||||
#endif /* GST_GL_HAVE_PLATFORM_GLX */
|
||||
#ifdef GST_GL_HAVE_PLATFORM_EGL
|
||||
if (!window && (!user_choice || g_strstr_len (user_choice, 3, "egl") != NULL))
|
||||
window = GST_GL_WINDOW_X11 (gst_gl_window_x11_egl_new ());
|
||||
#endif /* GST_GL_HAVE_PLATFORM_EGL */
|
||||
if (!window) {
|
||||
GST_WARNING ("Failed to create x11 window, user_choice:%s",
|
||||
user_choice ? user_choice : "NULL");
|
||||
return NULL;
|
||||
}
|
||||
gst_gl_window_set_need_lock (GST_GL_WINDOW (window), FALSE);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@ -228,27 +203,6 @@ gst_gl_window_x11_open (GstGLWindow * window, GError ** error)
|
|||
|
||||
GST_LOG ("gl display sender: %ld", (gulong) window_x11->disp_send);
|
||||
|
||||
return TRUE;
|
||||
|
||||
failure:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_gl_window_x11_create_context (GstGLWindow * window,
|
||||
GstGLAPI gl_api, guintptr external_gl_context, GError ** error)
|
||||
{
|
||||
GstGLWindowX11 *window_x11 = GST_GL_WINDOW_X11 (window);
|
||||
GstGLWindowX11Class *window_class = GST_GL_WINDOW_X11_GET_CLASS (window_x11);
|
||||
|
||||
setlocale (LC_NUMERIC, "C");
|
||||
|
||||
gst_gl_window_set_need_lock (GST_GL_WINDOW (window_x11), FALSE);
|
||||
|
||||
window_x11->running = TRUE;
|
||||
window_x11->visible = FALSE;
|
||||
window_x11->allow_extra_expose_events = TRUE;
|
||||
|
||||
g_assert (window_x11->device);
|
||||
|
||||
window_x11->screen = DefaultScreenOfDisplay (window_x11->device);
|
||||
|
@ -273,6 +227,28 @@ gst_gl_window_x11_create_context (GstGLWindow * window,
|
|||
|
||||
g_source_attach (window_x11->x11_source, window_x11->main_context);
|
||||
|
||||
window_x11->allow_extra_expose_events = TRUE;
|
||||
|
||||
return TRUE;
|
||||
|
||||
failure:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_gl_window_x11_create_context (GstGLWindow * window,
|
||||
GstGLAPI gl_api, guintptr external_gl_context, GError ** error)
|
||||
{
|
||||
GstGLWindowX11 *window_x11 = GST_GL_WINDOW_X11 (window);
|
||||
GstGLWindowX11Class *window_class = GST_GL_WINDOW_X11_GET_CLASS (window_x11);
|
||||
|
||||
setlocale (LC_NUMERIC, "C");
|
||||
|
||||
gst_gl_window_set_need_lock (GST_GL_WINDOW (window_x11), FALSE);
|
||||
|
||||
window_x11->running = TRUE;
|
||||
window_x11->visible = FALSE;
|
||||
|
||||
if (!window_class->choose_format (window_x11, error)) {
|
||||
goto failure;
|
||||
}
|
||||
|
@ -296,7 +272,7 @@ failure:
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gboolean
|
||||
gst_gl_window_x11_create_window (GstGLWindowX11 * window_x11)
|
||||
{
|
||||
XSetWindowAttributes win_attr;
|
||||
|
@ -373,9 +349,7 @@ void
|
|||
gst_gl_window_x11_close (GstGLWindow * window)
|
||||
{
|
||||
GstGLWindowX11 *window_x11 = GST_GL_WINDOW_X11 (window);
|
||||
GstGLWindowX11Class *window_class = GST_GL_WINDOW_X11_GET_CLASS (window_x11);
|
||||
XEvent event;
|
||||
Bool ret = TRUE;
|
||||
|
||||
GST_GL_WINDOW_LOCK (window_x11);
|
||||
|
||||
|
@ -383,11 +357,6 @@ gst_gl_window_x11_close (GstGLWindow * window)
|
|||
if (window_x11->internal_win_id)
|
||||
XUnmapWindow (window_x11->device, window_x11->internal_win_id);
|
||||
|
||||
ret = window_class->activate (window_x11, FALSE);
|
||||
if (!ret)
|
||||
GST_DEBUG ("failed to release opengl context");
|
||||
window_class->destroy_context (window_x11);
|
||||
|
||||
XFree (window_x11->visual_info);
|
||||
|
||||
if (window_x11->internal_win_id) {
|
||||
|
@ -482,7 +451,7 @@ gst_gl_window_x11_set_window_handle (GstGLWindow * window, guintptr id)
|
|||
|
||||
window_x11->parent_win = (Window) id;
|
||||
|
||||
if (window_x11->running) {
|
||||
if (g_main_loop_is_running (window_x11->loop)) {
|
||||
GST_LOG ("set parent window id: %lud", id);
|
||||
|
||||
g_mutex_lock (&window_x11->disp_send_lock);
|
||||
|
@ -499,6 +468,16 @@ gst_gl_window_x11_set_window_handle (GstGLWindow * window, guintptr id)
|
|||
}
|
||||
}
|
||||
|
||||
guintptr
|
||||
gst_gl_window_x11_get_window_handle (GstGLWindow * window)
|
||||
{
|
||||
GstGLWindowX11 *window_x11;
|
||||
|
||||
window_x11 = GST_GL_WINDOW_X11 (window);
|
||||
|
||||
return window_x11->internal_win_id;
|
||||
}
|
||||
|
||||
/* Called in the gl thread */
|
||||
void
|
||||
gst_gl_window_x11_draw_unlocked (GstGLWindow * window, guint width,
|
||||
|
@ -508,7 +487,8 @@ gst_gl_window_x11_draw_unlocked (GstGLWindow * window, guint width,
|
|||
|
||||
window_x11 = GST_GL_WINDOW_X11 (window);
|
||||
|
||||
if (window_x11->running && window_x11->allow_extra_expose_events) {
|
||||
if (g_main_loop_is_running (window_x11->loop)
|
||||
&& window_x11->allow_extra_expose_events) {
|
||||
XEvent event;
|
||||
XWindowAttributes attr;
|
||||
|
||||
|
@ -539,7 +519,7 @@ gst_gl_window_x11_draw (GstGLWindow * window, guint width, guint height)
|
|||
|
||||
window_x11 = GST_GL_WINDOW_X11 (window);
|
||||
|
||||
if (window_x11->running) {
|
||||
if (g_main_loop_is_running (window_x11->loop)) {
|
||||
XEvent event;
|
||||
XWindowAttributes attr;
|
||||
|
||||
|
@ -634,26 +614,63 @@ gst_gl_window_x11_run (GstGLWindow * window)
|
|||
g_main_loop_run (window_x11->loop);
|
||||
}
|
||||
|
||||
inline gchar *
|
||||
event_type_to_string (guint type)
|
||||
{
|
||||
switch (type) {
|
||||
case CreateNotify:
|
||||
return "CreateNotify";
|
||||
case ConfigureNotify:
|
||||
return "ConfigureNotify";
|
||||
case DestroyNotify:
|
||||
return "DestroyNotify";
|
||||
case MapNotify:
|
||||
return "MapNotify";
|
||||
case UnmapNotify:
|
||||
return "UnmapNotify";
|
||||
case Expose:
|
||||
return "Expose";
|
||||
case VisibilityNotify:
|
||||
return "VisibilityNotify";
|
||||
case PropertyNotify:
|
||||
return "PropertyNotify";
|
||||
case SelectionClear:
|
||||
return "SelectionClear";
|
||||
case SelectionNotify:
|
||||
return "SelectionNotify";
|
||||
case SelectionRequest:
|
||||
return "SelectionRequest";
|
||||
case ClientMessage:
|
||||
return "ClientMessage";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_gl_window_x11_handle_event (GstGLWindowX11 * window_x11)
|
||||
{
|
||||
GstGLContext *context;
|
||||
GstGLContextClass *context_class;
|
||||
GstGLWindow *window;
|
||||
GstGLWindowX11Class *window_class;
|
||||
|
||||
gboolean ret = TRUE;
|
||||
|
||||
window = GST_GL_WINDOW (window_x11);
|
||||
window_class = GST_GL_WINDOW_X11_GET_CLASS (window_x11);
|
||||
context = gst_gl_window_get_context (window);
|
||||
context_class = GST_GL_CONTEXT_GET_CLASS (context);
|
||||
|
||||
if (window_x11->running && XPending (window_x11->device)) {
|
||||
if (g_main_loop_is_running (window_x11->loop)
|
||||
&& XPending (window_x11->device)) {
|
||||
XEvent event;
|
||||
|
||||
/* XSendEvent (which are called in other threads) are done from another display structure */
|
||||
XNextEvent (window_x11->device, &event);
|
||||
|
||||
// use in generic/cube and other related uses
|
||||
window_x11->allow_extra_expose_events = XPending (window_x11->device) <= 2;
|
||||
|
||||
GST_LOG ("got event %s", event_type_to_string (event.type));
|
||||
|
||||
switch (event.type) {
|
||||
case ClientMessage:
|
||||
{
|
||||
|
@ -690,7 +707,7 @@ gst_gl_window_x11_handle_event (GstGLWindowX11 * window_x11)
|
|||
case Expose:
|
||||
if (window->draw) {
|
||||
window->draw (window->draw_data);
|
||||
window_class->swap_buffers (window_x11);
|
||||
context_class->swap_buffers (context);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -719,12 +736,14 @@ gst_gl_window_x11_handle_event (GstGLWindowX11 * window_x11)
|
|||
}
|
||||
|
||||
default:
|
||||
GST_DEBUG ("unknown XEvent type: %ud", event.type);
|
||||
GST_DEBUG ("unknown XEvent type: %u", event.type);
|
||||
break;
|
||||
|
||||
} // switch
|
||||
} // while running
|
||||
|
||||
gst_object_unref (context);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -752,7 +771,7 @@ gst_gl_window_x11_send_message (GstGLWindow * window, GstGLWindowCB callback,
|
|||
|
||||
window_x11 = GST_GL_WINDOW_X11 (window);
|
||||
|
||||
if (window_x11->running) {
|
||||
if (g_main_loop_is_running (window_x11->loop)) {
|
||||
GstGLMessage message;
|
||||
|
||||
message.window = window;
|
||||
|
@ -807,3 +826,13 @@ gst_gl_window_x11_untrap_x_errors (void)
|
|||
|
||||
return TrappedErrorCode;
|
||||
}
|
||||
|
||||
guintptr
|
||||
gst_gl_window_x11_get_display (GstGLWindow * window)
|
||||
{
|
||||
GstGLWindowX11 *window_x11;
|
||||
|
||||
window_x11 = GST_GL_WINDOW_X11 (window);
|
||||
|
||||
return (guintptr) window_x11->device;
|
||||
}
|
||||
|
|
|
@ -103,6 +103,8 @@ GstGLWindowX11 * gst_gl_window_x11_new (void);
|
|||
void gst_gl_window_x11_trap_x_errors (void);
|
||||
gint gst_gl_window_x11_untrap_x_errors (void);
|
||||
|
||||
gboolean gst_gl_window_x11_create_window (GstGLWindowX11 * window_x11);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_GL_WINDOW_X11_H__ */
|
||||
|
|
|
@ -1,203 +0,0 @@
|
|||
/*
|
||||
* GStreamer
|
||||
* Copyright (C) 2008 Julien Isorce <julien.isorce@gmail.com>
|
||||
* Copyright (C) 2012 Matthew Waters <ystreet00@gmail.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.
|
||||
*/
|
||||
|
||||
#define GLIB_DISABLE_DEPRECATION_WARNINGS
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "../gstgl_fwd.h"
|
||||
#include <gst/gl/gstglcontext.h>
|
||||
|
||||
#include "gstglwindow_x11_egl.h"
|
||||
|
||||
const gchar *X11EGLErrorString ();
|
||||
|
||||
#define GST_CAT_DEFAULT gst_gl_window_debug
|
||||
|
||||
#define gst_gl_window_x11_egl_parent_class parent_class
|
||||
G_DEFINE_TYPE (GstGLWindowX11EGL, gst_gl_window_x11_egl,
|
||||
GST_GL_TYPE_WINDOW_X11);
|
||||
|
||||
static guintptr gst_gl_window_x11_egl_get_gl_context (GstGLWindowX11 *
|
||||
window_x11);
|
||||
static void gst_gl_window_x11_egl_swap_buffers (GstGLWindowX11 * window_x11);
|
||||
static gboolean gst_gl_window_x11_egl_activate (GstGLWindowX11 * window_x11,
|
||||
gboolean activate);
|
||||
static gboolean gst_gl_window_x11_egl_create_context (GstGLWindowX11 *
|
||||
window_x11, GstGLAPI gl_api, guintptr external_gl_context, GError ** error);
|
||||
static void gst_gl_window_x11_egl_destroy_context (GstGLWindowX11 * window_x11);
|
||||
static gboolean gst_gl_window_x11_egl_choose_format (GstGLWindowX11 *
|
||||
window_x11, GError ** error);
|
||||
GstGLAPI gst_gl_window_x11_egl_get_gl_api (GstGLWindow * window);
|
||||
static gpointer gst_gl_window_x11_egl_get_proc_address (GstGLWindow * window,
|
||||
const gchar * name);
|
||||
|
||||
static void
|
||||
gst_gl_window_x11_egl_class_init (GstGLWindowX11EGLClass * klass)
|
||||
{
|
||||
GstGLWindowClass *window_class = (GstGLWindowClass *) klass;
|
||||
GstGLWindowX11Class *window_x11_class = (GstGLWindowX11Class *) klass;
|
||||
|
||||
window_x11_class->get_gl_context =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_x11_egl_get_gl_context);
|
||||
window_x11_class->activate =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_x11_egl_activate);
|
||||
window_x11_class->create_context =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_x11_egl_create_context);
|
||||
window_x11_class->destroy_context =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_x11_egl_destroy_context);
|
||||
window_x11_class->choose_format =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_x11_egl_choose_format);
|
||||
window_x11_class->swap_buffers =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_x11_egl_swap_buffers);
|
||||
|
||||
window_class->get_gl_api =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_x11_egl_get_gl_api);
|
||||
window_class->get_proc_address =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_x11_egl_get_proc_address);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_window_x11_egl_init (GstGLWindowX11EGL * window)
|
||||
{
|
||||
}
|
||||
|
||||
/* Must be called in the gl thread */
|
||||
GstGLWindowX11EGL *
|
||||
gst_gl_window_x11_egl_new (void)
|
||||
{
|
||||
GstGLWindowX11EGL *window = g_object_new (GST_GL_TYPE_WINDOW_X11_EGL, NULL);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_gl_window_x11_egl_choose_format (GstGLWindowX11 * window_x11,
|
||||
GError ** error)
|
||||
{
|
||||
gint ret;
|
||||
|
||||
window_x11->visual_info = g_new0 (XVisualInfo, 1);
|
||||
ret = XMatchVisualInfo (window_x11->device, window_x11->screen_num,
|
||||
window_x11->depth, TrueColor, window_x11->visual_info);
|
||||
|
||||
if (ret == 0) {
|
||||
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_WRONG_CONFIG,
|
||||
"Failed to match XVisualInfo");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_gl_window_x11_egl_create_context (GstGLWindowX11 * window_x11,
|
||||
GstGLAPI gl_api, guintptr external_gl_context, GError ** error)
|
||||
{
|
||||
GstGLWindowX11EGL *window_egl;
|
||||
|
||||
if ((gl_api & GST_GL_API_OPENGL) == GST_GL_API_NONE &&
|
||||
(gl_api & GST_GL_API_GLES2) == GST_GL_API_NONE) {
|
||||
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_WRONG_API,
|
||||
"xEGL supports opengl or gles2");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
window_egl = GST_GL_WINDOW_X11_EGL (window_x11);
|
||||
|
||||
window_egl->egl =
|
||||
gst_gl_egl_create_context (eglGetDisplay ((EGLNativeDisplayType)
|
||||
window_x11->device),
|
||||
(EGLNativeWindowType) window_x11->internal_win_id, gl_api,
|
||||
external_gl_context, error);
|
||||
if (!window_egl->egl)
|
||||
goto failure;
|
||||
|
||||
return TRUE;
|
||||
|
||||
failure:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_window_x11_egl_destroy_context (GstGLWindowX11 * window_x11)
|
||||
{
|
||||
GstGLWindowX11EGL *window_egl;
|
||||
|
||||
window_egl = GST_GL_WINDOW_X11_EGL (window_x11);
|
||||
|
||||
gst_gl_egl_destroy_context (window_egl->egl);
|
||||
window_egl->egl = NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_gl_window_x11_egl_activate (GstGLWindowX11 * window_x11, gboolean activate)
|
||||
{
|
||||
GstGLWindowX11EGL *window_egl;
|
||||
|
||||
window_egl = GST_GL_WINDOW_X11_EGL (window_x11);
|
||||
|
||||
return gst_gl_egl_activate (window_egl->egl, activate);
|
||||
}
|
||||
|
||||
static guintptr
|
||||
gst_gl_window_x11_egl_get_gl_context (GstGLWindowX11 * window_x11)
|
||||
{
|
||||
GstGLWindowX11EGL *window_egl;
|
||||
|
||||
window_egl = GST_GL_WINDOW_X11_EGL (window_x11);
|
||||
|
||||
return gst_gl_egl_get_gl_context (window_egl->egl);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_window_x11_egl_swap_buffers (GstGLWindowX11 * window_x11)
|
||||
{
|
||||
GstGLWindowX11EGL *window_egl = GST_GL_WINDOW_X11_EGL (window_x11);
|
||||
|
||||
gst_gl_egl_swap_buffers (window_egl->egl);
|
||||
}
|
||||
|
||||
GstGLAPI
|
||||
gst_gl_window_x11_egl_get_gl_api (GstGLWindow * window)
|
||||
{
|
||||
GstGLWindowX11EGL *window_egl = GST_GL_WINDOW_X11_EGL (window);
|
||||
|
||||
return window_egl->egl ? gst_gl_egl_get_gl_api (window_egl->
|
||||
egl) : GST_GL_API_GLES2 | GST_GL_API_OPENGL;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
gst_gl_window_x11_egl_get_proc_address (GstGLWindow * window,
|
||||
const gchar * name)
|
||||
{
|
||||
GstGLContext *context = NULL;
|
||||
GstGLWindowX11EGL *window_egl = GST_GL_WINDOW_X11_EGL (window);
|
||||
gpointer result;
|
||||
|
||||
if (!(result = gst_gl_egl_get_proc_address (window_egl->egl, name))) {
|
||||
result = gst_gl_context_default_get_proc_address (context, name);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
/*
|
||||
* GStreamer
|
||||
* Copyright (C) 2012 Matthew Waters <ystreet00@gmail.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 __GST_GL_WINDOW_X11_EGL_H__
|
||||
#define __GST_GL_WINDOW_X11_EGL_H__
|
||||
|
||||
#include "gstglwindow_x11.h"
|
||||
#include "../gstglegl.h"
|
||||
|
||||
#include <EGL/egl.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_GL_TYPE_WINDOW_X11_EGL (gst_gl_window_x11_egl_get_type())
|
||||
#define GST_GL_WINDOW_X11_EGL(o) (G_TYPE_CHECK_INSTANCE_CAST((o), GST_GL_TYPE_WINDOW_X11_EGL, GstGLWindowX11EGL))
|
||||
#define GST_GL_WINDOW_X11_EGL_CLASS(k) (G_TYPE_CHECK_CLASS((k), GST_GL_TYPE_WINDOW_X11_EGL, GstGLWindowX11EGLClass))
|
||||
#define GST_GL_IS_WINDOW_X11_EGL(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), GST_GL_TYPE_WINDOW_X11_EGL))
|
||||
#define GST_GL_IS_WINDOW_X11_EGL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), GST_GL_TYPE_WINDOW_X11_EGL))
|
||||
#define GST_GL_WINDOW_X11_EGL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_GL_TYPE_WINDOW_X11_EGL, GstGLWindowX11EGL_Class))
|
||||
|
||||
typedef struct _GstGLWindowX11EGL GstGLWindowX11EGL;
|
||||
typedef struct _GstGLWindowX11EGLClass GstGLWindowX11EGLClass;
|
||||
|
||||
struct _GstGLWindowX11EGL {
|
||||
/*< private >*/
|
||||
GstGLWindowX11 parent;
|
||||
|
||||
GstGLEGL *egl;
|
||||
|
||||
gpointer _reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
struct _GstGLWindowX11EGLClass {
|
||||
/*< private >*/
|
||||
GstGLWindowX11Class parent_class;
|
||||
|
||||
/*< private >*/
|
||||
gpointer _reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
GType gst_gl_window_x11_egl_get_type (void);
|
||||
|
||||
GstGLWindowX11EGL * gst_gl_window_x11_egl_new (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_GL_WINDOW_X11_H__ */
|
|
@ -1,366 +0,0 @@
|
|||
/*
|
||||
* GStreamer
|
||||
* Copyright (C) 2008 Julien Isorce <julien.isorce@gmail.com>
|
||||
* Copyright (C) 2012 Matthew Waters <ystreet00@gmail.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.
|
||||
*/
|
||||
|
||||
#define GLIB_DISABLE_DEPRECATION_WARNINGS
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "../gstgl_fwd.h"
|
||||
#include <gst/gl/gstglcontext.h>
|
||||
|
||||
#include <gst/gl/gl.h>
|
||||
#include "gstglwindow_x11_glx.h"
|
||||
|
||||
#define GST_CAT_DEFAULT gst_gl_window_debug
|
||||
|
||||
#define gst_gl_window_x11_glx_parent_class parent_class
|
||||
G_DEFINE_TYPE (GstGLWindowX11GLX, gst_gl_window_x11_glx,
|
||||
GST_GL_TYPE_WINDOW_X11);
|
||||
|
||||
#define GST_GL_WINDOW_X11_GLX_GET_PRIVATE(o) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE((o), GST_GL_TYPE_WINDOW_X11_GLX, GstGLWindowX11GLXPrivate))
|
||||
|
||||
static guintptr gst_gl_window_x11_glx_get_gl_context (GstGLWindowX11 *
|
||||
window_x11);
|
||||
static void gst_gl_window_x11_glx_swap_buffers (GstGLWindowX11 * window_x11);
|
||||
static gboolean gst_gl_window_x11_glx_activate (GstGLWindowX11 * window_x11,
|
||||
gboolean activate);
|
||||
static gboolean gst_gl_window_x11_glx_create_context (GstGLWindowX11 *
|
||||
window_x11, GstGLAPI gl_api, guintptr external_gl_context, GError ** error);
|
||||
static void gst_gl_window_x11_glx_destroy_context (GstGLWindowX11 * window_x11);
|
||||
static gboolean gst_gl_window_x11_glx_choose_format (GstGLWindowX11 *
|
||||
window_x11, GError ** error);
|
||||
GstGLAPI gst_gl_window_x11_glx_get_gl_api (GstGLWindow * window);
|
||||
static gpointer gst_gl_window_x11_glx_get_proc_address (GstGLWindow * window,
|
||||
const gchar * name);
|
||||
|
||||
struct _GstGLWindowX11GLXPrivate
|
||||
{
|
||||
int glx_major;
|
||||
int glx_minor;
|
||||
|
||||
GstGLAPI context_api;
|
||||
|
||||
GLXFBConfig *fbconfigs;
|
||||
GLXContext (*glXCreateContextAttribsARB) (Display *, GLXFBConfig,
|
||||
GLXContext, Bool, const int *);
|
||||
};
|
||||
|
||||
static void
|
||||
gst_gl_window_x11_glx_class_init (GstGLWindowX11GLXClass * klass)
|
||||
{
|
||||
GstGLWindowClass *window_class = (GstGLWindowClass *) klass;
|
||||
GstGLWindowX11Class *window_x11_class = (GstGLWindowX11Class *) klass;
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GstGLWindowX11GLXPrivate));
|
||||
|
||||
window_x11_class->get_gl_context =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_x11_glx_get_gl_context);
|
||||
window_x11_class->activate =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_x11_glx_activate);
|
||||
window_x11_class->create_context =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_x11_glx_create_context);
|
||||
window_x11_class->destroy_context =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_x11_glx_destroy_context);
|
||||
window_x11_class->choose_format =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_x11_glx_choose_format);
|
||||
window_x11_class->swap_buffers =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_x11_glx_swap_buffers);
|
||||
|
||||
window_class->get_gl_api =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_x11_glx_get_gl_api);
|
||||
window_class->get_proc_address =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_x11_glx_get_proc_address);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_window_x11_glx_init (GstGLWindowX11GLX * window)
|
||||
{
|
||||
window->priv = GST_GL_WINDOW_X11_GLX_GET_PRIVATE (window);
|
||||
}
|
||||
|
||||
/* Must be called in the gl thread */
|
||||
GstGLWindowX11GLX *
|
||||
gst_gl_window_x11_glx_new (void)
|
||||
{
|
||||
GstGLWindowX11GLX *window = g_object_new (GST_GL_TYPE_WINDOW_X11_GLX, NULL);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_describe_fbconfig (Display * display, GLXFBConfig config)
|
||||
{
|
||||
int val;
|
||||
|
||||
glXGetFBConfigAttrib (display, config, GLX_FBCONFIG_ID, &val);
|
||||
GST_DEBUG ("ID: %d", val);
|
||||
glXGetFBConfigAttrib (display, config, GLX_DOUBLEBUFFER, &val);
|
||||
GST_DEBUG ("double buffering: %d", val);
|
||||
glXGetFBConfigAttrib (display, config, GLX_RED_SIZE, &val);
|
||||
GST_DEBUG ("red: %d", val);
|
||||
glXGetFBConfigAttrib (display, config, GLX_GREEN_SIZE, &val);
|
||||
GST_DEBUG ("green: %d", val);
|
||||
glXGetFBConfigAttrib (display, config, GLX_BLUE_SIZE, &val);
|
||||
GST_DEBUG ("blue: %d", val);
|
||||
glXGetFBConfigAttrib (display, config, GLX_ALPHA_SIZE, &val);
|
||||
GST_DEBUG ("alpha: %d", val);
|
||||
glXGetFBConfigAttrib (display, config, GLX_DEPTH_SIZE, &val);
|
||||
GST_DEBUG ("depth: %d", val);
|
||||
glXGetFBConfigAttrib (display, config, GLX_STENCIL_SIZE, &val);
|
||||
GST_DEBUG ("stencil: %d", val);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_gl_window_x11_glx_create_context (GstGLWindowX11 * window_x11,
|
||||
GstGLAPI gl_api, guintptr external_gl_context, GError ** error)
|
||||
{
|
||||
GstGLWindowX11GLX *window_glx;
|
||||
gboolean create_context;
|
||||
const char *glx_exts;
|
||||
int x_error;
|
||||
|
||||
window_glx = GST_GL_WINDOW_X11_GLX (window_x11);
|
||||
|
||||
glx_exts =
|
||||
glXQueryExtensionsString (window_x11->device,
|
||||
DefaultScreen (window_x11->device));
|
||||
|
||||
create_context = gst_gl_check_extension ("GLX_ARB_create_context", glx_exts);
|
||||
window_glx->priv->glXCreateContextAttribsARB =
|
||||
(gpointer) glXGetProcAddressARB ((const GLubyte *)
|
||||
"glXCreateContextAttribsARB");
|
||||
|
||||
if (create_context && window_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,
|
||||
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 ();
|
||||
window_glx->glx_context =
|
||||
window_glx->priv->glXCreateContextAttribsARB (window_x11->device,
|
||||
window_glx->priv->fbconfigs[0], (GLXContext) external_gl_context, True,
|
||||
context_attribs_3);
|
||||
|
||||
x_error = gst_gl_window_x11_untrap_x_errors ();
|
||||
window_glx->priv->context_api = GST_GL_API_OPENGL3 | GST_GL_API_OPENGL;
|
||||
|
||||
if (!window_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 ();
|
||||
window_glx->glx_context =
|
||||
window_glx->priv->glXCreateContextAttribsARB (window_x11->device,
|
||||
window_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)
|
||||
window_glx->glx_context = NULL;
|
||||
window_glx->priv->context_api = GST_GL_API_OPENGL;
|
||||
}
|
||||
|
||||
} else {
|
||||
window_glx->glx_context =
|
||||
glXCreateContext (window_x11->device, window_x11->visual_info,
|
||||
(GLXContext) external_gl_context, TRUE);
|
||||
window_glx->priv->context_api = GST_GL_API_OPENGL;
|
||||
}
|
||||
|
||||
if (window_glx->priv->fbconfigs)
|
||||
XFree (window_glx->priv->fbconfigs);
|
||||
|
||||
if (!window_glx->glx_context) {
|
||||
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_CREATE_CONTEXT,
|
||||
"Failed to create opengl context");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
GST_LOG ("gl context id: %ld", (gulong) window_glx->glx_context);
|
||||
|
||||
return TRUE;
|
||||
|
||||
failure:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_window_x11_glx_destroy_context (GstGLWindowX11 * window_x11)
|
||||
{
|
||||
GstGLWindowX11GLX *window_glx;
|
||||
|
||||
window_glx = GST_GL_WINDOW_X11_GLX (window_x11);
|
||||
|
||||
glXDestroyContext (window_x11->device, window_glx->glx_context);
|
||||
|
||||
window_glx->glx_context = 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_gl_window_x11_glx_choose_format (GstGLWindowX11 * window_x11,
|
||||
GError ** error)
|
||||
{
|
||||
GstGLWindowX11GLX *window_glx;
|
||||
gint error_base;
|
||||
gint event_base;
|
||||
|
||||
window_glx = GST_GL_WINDOW_X11_GLX (window_x11);
|
||||
|
||||
if (!glXQueryExtension (window_x11->device, &error_base, &event_base)) {
|
||||
g_set_error (error, GST_GL_WINDOW_ERROR,
|
||||
GST_GL_WINDOW_ERROR_RESOURCE_UNAVAILABLE, "No GLX extension");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (!glXQueryVersion (window_x11->device, &window_glx->priv->glx_major,
|
||||
&window_glx->priv->glx_minor)) {
|
||||
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_CREATE_CONTEXT,
|
||||
"Failed to query GLX version (glXQueryVersion failed)");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
GST_INFO ("GLX Version: %d.%d", window_glx->priv->glx_major,
|
||||
window_glx->priv->glx_minor);
|
||||
|
||||
/* legacy case */
|
||||
if (window_glx->priv->glx_major < 1 || (window_glx->priv->glx_major == 1
|
||||
&& window_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 (window_x11->device,
|
||||
window_x11->screen_num, attribs);
|
||||
|
||||
if (!window_x11->visual_info) {
|
||||
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_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;
|
||||
|
||||
window_glx->priv->fbconfigs = glXChooseFBConfig (window_x11->device,
|
||||
DefaultScreen (window_x11->device), attribs, &fbcount);
|
||||
|
||||
if (!window_glx->priv->fbconfigs) {
|
||||
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_WRONG_CONFIG,
|
||||
"Could not find any FBConfig's to use (check attributes?)");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
_describe_fbconfig (window_x11->device, window_glx->priv->fbconfigs[0]);
|
||||
|
||||
window_x11->visual_info = glXGetVisualFromFBConfig (window_x11->device,
|
||||
window_glx->priv->fbconfigs[0]);
|
||||
|
||||
if (!window_x11->visual_info) {
|
||||
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_WRONG_CONFIG,
|
||||
"Bad attributes in FBConfig");
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
failure:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_window_x11_glx_swap_buffers (GstGLWindowX11 * window_x11)
|
||||
{
|
||||
glXSwapBuffers (window_x11->device, window_x11->internal_win_id);
|
||||
}
|
||||
|
||||
static guintptr
|
||||
gst_gl_window_x11_glx_get_gl_context (GstGLWindowX11 * window_x11)
|
||||
{
|
||||
return (guintptr) GST_GL_WINDOW_X11_GLX (window_x11)->glx_context;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_gl_window_x11_glx_activate (GstGLWindowX11 * window_x11, gboolean activate)
|
||||
{
|
||||
gboolean result;
|
||||
|
||||
if (activate) {
|
||||
result = glXMakeCurrent (window_x11->device, window_x11->internal_win_id,
|
||||
GST_GL_WINDOW_X11_GLX (window_x11)->glx_context);
|
||||
} else {
|
||||
result = glXMakeCurrent (window_x11->device, None, NULL);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
GstGLAPI
|
||||
gst_gl_window_x11_glx_get_gl_api (GstGLWindow * window)
|
||||
{
|
||||
GstGLWindowX11GLX *window_glx;
|
||||
|
||||
window_glx = GST_GL_WINDOW_X11_GLX (window);
|
||||
|
||||
return window_glx->priv->context_api;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
gst_gl_window_x11_glx_get_proc_address (GstGLWindow * window,
|
||||
const gchar * name)
|
||||
{
|
||||
GstGLContext *context = NULL;
|
||||
gpointer result;
|
||||
|
||||
if (!(result = glXGetProcAddressARB ((const GLubyte *) name))) {
|
||||
result = gst_gl_context_default_get_proc_address (context, name);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
/*
|
||||
* GStreamer
|
||||
* Copyright (C) 2012 Matthew Waters <ystreet00@gmail.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 __GST_GL_WINDOW_X11_GLX_H__
|
||||
#define __GST_GL_WINDOW_X11_GLX_H__
|
||||
|
||||
#include "gstglwindow_x11.h"
|
||||
|
||||
#include <GL/glx.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_GL_TYPE_WINDOW_X11_GLX (gst_gl_window_x11_glx_get_type())
|
||||
#define GST_GL_WINDOW_X11_GLX(o) (G_TYPE_CHECK_INSTANCE_CAST((o), GST_GL_TYPE_WINDOW_X11_GLX, GstGLWindowX11GLX))
|
||||
#define GST_GL_WINDOW_X11_GLX_CLASS(k) (G_TYPE_CHECK_CLASS((k), GST_GL_TYPE_WINDOW_X11_GLX, GstGLWindowX11GLXClass))
|
||||
#define GST_GL_IS_WINDOW_X11_GLX(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), GST_GL_TYPE_WINDOW_X11_GLX))
|
||||
#define GST_GL_IS_WINDOW_X11_GLX_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), GST_GL_TYPE_WINDOW_X11_GLX))
|
||||
#define GST_GL_WINDOW_X11_GLX_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_GL_TYPE_WINDOW_X11_GLX, GstGLWindowX11GLX_Class))
|
||||
|
||||
typedef struct _GstGLWindowX11GLX GstGLWindowX11GLX;
|
||||
typedef struct _GstGLWindowX11GLXClass GstGLWindowX11GLXClass;
|
||||
typedef struct _GstGLWindowX11GLXPrivate GstGLWindowX11GLXPrivate;
|
||||
|
||||
struct _GstGLWindowX11GLX {
|
||||
/*< private >*/
|
||||
GstGLWindowX11 parent;
|
||||
|
||||
GLXContext glx_context;
|
||||
|
||||
GstGLWindowX11GLXPrivate *priv;
|
||||
|
||||
gpointer _reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
struct _GstGLWindowX11GLXClass {
|
||||
/*< private >*/
|
||||
GstGLWindowX11Class parent_class;
|
||||
|
||||
/*< private >*/
|
||||
gpointer _reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
GType gst_gl_window_x11_glx_get_type (void);
|
||||
|
||||
GstGLWindowX11GLX * gst_gl_window_x11_glx_new (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_GL_WINDOW_X11_H__ */
|
Loading…
Reference in a new issue