3 * Copyright (C) 2008 Julien Isorce <julien.isorce@gmail.com>
4 * Copyright (C) 2012 Matthew Waters <ystreet00@gmail.com>
5 * Copyright (C) 2013 Sebastian Dröge <slomo@circular-chaos.org>
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
23 /* TODO: - Window resize handling
24 * - Event handling input event handling
33 #include <gst/gl/egl/gstglcontext_egl.h>
34 #include "gstglwindow_android_egl.h"
36 #define GST_CAT_DEFAULT gst_gl_window_debug
38 #define gst_gl_window_android_egl_parent_class parent_class
39 G_DEFINE_TYPE (GstGLWindowAndroidEGL, gst_gl_window_android_egl,
41 static void gst_gl_window_android_egl_finalize (GObject * object);
43 static guintptr gst_gl_window_android_egl_get_display (GstGLWindow * window);
44 static guintptr gst_gl_window_android_egl_get_window_handle (GstGLWindow *
46 static void gst_gl_window_android_egl_set_window_handle (GstGLWindow * window,
48 static void gst_gl_window_android_egl_draw (GstGLWindow * window);
49 static void gst_gl_window_android_egl_run (GstGLWindow * window);
50 static void gst_gl_window_android_egl_quit (GstGLWindow * window);
51 static void gst_gl_window_android_egl_send_message_async (GstGLWindow * window,
52 GstGLWindowCB callback, gpointer data, GDestroyNotify destroy);
53 static gboolean gst_gl_window_android_egl_open (GstGLWindow * window,
55 static void gst_gl_window_android_egl_close (GstGLWindow * window);
58 gst_gl_window_android_egl_class_init (GstGLWindowAndroidEGLClass * klass)
60 GstGLWindowClass *window_class = (GstGLWindowClass *) klass;
61 GObjectClass *gobject_class = (GObjectClass *) klass;
63 window_class->get_display =
64 GST_DEBUG_FUNCPTR (gst_gl_window_android_egl_get_display);
65 window_class->get_window_handle =
66 GST_DEBUG_FUNCPTR (gst_gl_window_android_egl_get_window_handle);
67 window_class->set_window_handle =
68 GST_DEBUG_FUNCPTR (gst_gl_window_android_egl_set_window_handle);
69 window_class->draw_unlocked =
70 GST_DEBUG_FUNCPTR (gst_gl_window_android_egl_draw);
71 window_class->draw = GST_DEBUG_FUNCPTR (gst_gl_window_android_egl_draw);
72 window_class->run = GST_DEBUG_FUNCPTR (gst_gl_window_android_egl_run);
73 window_class->quit = GST_DEBUG_FUNCPTR (gst_gl_window_android_egl_quit);
74 window_class->send_message_async =
75 GST_DEBUG_FUNCPTR (gst_gl_window_android_egl_send_message_async);
76 window_class->open = GST_DEBUG_FUNCPTR (gst_gl_window_android_egl_open);
77 window_class->close = GST_DEBUG_FUNCPTR (gst_gl_window_android_egl_close);
79 gobject_class->finalize = gst_gl_window_android_egl_finalize;
83 gst_gl_window_android_egl_init (GstGLWindowAndroidEGL * window)
85 window->main_context = g_main_context_new ();
86 window->loop = g_main_loop_new (window->main_context, FALSE);
90 gst_gl_window_android_egl_finalize (GObject * object)
92 GstGLWindowAndroidEGL *window_egl = GST_GL_WINDOW_ANDROID_EGL (object);
94 g_main_loop_unref (window_egl->loop);
95 g_main_context_unref (window_egl->main_context);
97 G_OBJECT_CLASS (parent_class)->finalize (object);
100 /* Must be called in the gl thread */
101 GstGLWindowAndroidEGL *
102 gst_gl_window_android_egl_new (void)
104 GstGLWindowAndroidEGL *window;
106 GST_DEBUG ("creating Android EGL window");
108 window = g_object_new (GST_GL_TYPE_WINDOW_ANDROID_EGL, NULL);
114 gst_gl_window_android_egl_open (GstGLWindow * window, GError ** error)
120 gst_gl_window_android_egl_close (GstGLWindow * window)
125 gst_gl_window_android_egl_run (GstGLWindow * window)
127 GstGLWindowAndroidEGL *window_egl;
129 window_egl = GST_GL_WINDOW_ANDROID_EGL (window);
131 GST_LOG ("starting main loop");
132 g_main_loop_run (window_egl->loop);
133 GST_LOG ("exiting main loop");
137 gst_gl_window_android_egl_quit (GstGLWindow * window)
139 GstGLWindowAndroidEGL *window_egl;
141 window_egl = GST_GL_WINDOW_ANDROID_EGL (window);
143 GST_LOG ("sending quit");
145 g_main_loop_quit (window_egl->loop);
147 GST_LOG ("quit sent");
150 typedef struct _GstGLMessage
152 GstGLWindowCB callback;
154 GDestroyNotify destroy;
158 _run_message (GstGLMessage * message)
160 if (message->callback)
161 message->callback (message->data);
163 if (message->destroy)
164 message->destroy (message->data);
166 g_slice_free (GstGLMessage, message);
172 gst_gl_window_android_egl_send_message_async (GstGLWindow * window,
173 GstGLWindowCB callback, gpointer data, GDestroyNotify destroy)
175 GstGLWindowAndroidEGL *window_egl;
176 GstGLMessage *message;
178 window_egl = GST_GL_WINDOW_ANDROID_EGL (window);
179 message = g_slice_new (GstGLMessage);
181 message->callback = callback;
182 message->data = data;
183 message->destroy = destroy;
185 g_main_context_invoke (window_egl->main_context, (GSourceFunc) _run_message,
190 gst_gl_window_android_egl_set_window_handle (GstGLWindow * window,
193 GstGLWindowAndroidEGL *window_egl = GST_GL_WINDOW_ANDROID_EGL (window);
195 window_egl->native_window = (EGLNativeWindowType) handle;
199 gst_gl_window_android_egl_get_window_handle (GstGLWindow * window)
201 GstGLWindowAndroidEGL *window_egl = GST_GL_WINDOW_ANDROID_EGL (window);
203 return (guintptr) window_egl->native_window;
207 draw_cb (gpointer data)
209 GstGLWindowAndroidEGL *window_egl = data;
210 GstGLWindow *window = GST_GL_WINDOW (window_egl);
211 GstGLContext *context = gst_gl_window_get_context (window);
212 GstGLContextEGL *context_egl = GST_GL_CONTEXT_EGL (context);
213 GstGLContextClass *context_class = GST_GL_CONTEXT_GET_CLASS (context);
215 if (context_egl->egl_surface) {
218 if (eglQuerySurface (context_egl->egl_display,
219 context_egl->egl_surface, EGL_WIDTH, &width) &&
220 eglQuerySurface (context_egl->egl_display,
221 context_egl->egl_surface, EGL_HEIGHT, &height)
222 && (width != window_egl->window_width
223 || height != window_egl->window_height)) {
224 window_egl->window_width = width;
225 window_egl->window_height = height;
228 window->resize (window->resize_data, width, height);
233 window->draw (window->draw_data);
235 context_class->swap_buffers (context);
237 gst_object_unref (context);
241 gst_gl_window_android_egl_draw (GstGLWindow * window)
243 gst_gl_window_send_message (window, (GstGLWindowCB) draw_cb, window);
247 gst_gl_window_android_egl_get_display (GstGLWindow * window)