#define gst_gl_window_wayland_egl_parent_class parent_class
G_DEFINE_TYPE (GstGLWindowWaylandEGL, gst_gl_window_wayland_egl,
GST_GL_TYPE_WINDOW);
-static void gst_gl_window_wayland_egl_finalize (GObject * object);
static guintptr gst_gl_window_wayland_egl_get_window_handle (GstGLWindow *
window);
guintptr handle);
static void gst_gl_window_wayland_egl_show (GstGLWindow * window);
static void gst_gl_window_wayland_egl_draw (GstGLWindow * window);
-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_async (GstGLWindow * window,
- GstGLWindowCB callback, gpointer data, GDestroyNotify destroy);
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 gboolean gst_gl_window_wayland_egl_set_render_rectangle (GstGLWindow *
+ window, gint x, gint y, gint width, gint height);
#if 0
static void
};
static void
-surface_handle_enter (void *data, struct wl_surface *wl_surface,
- struct wl_output *output)
-{
-}
-
-static void
-surface_handle_leave (void *data, struct wl_surface *wl_surface,
- struct wl_output *output)
-{
-}
-
-static const struct wl_surface_listener surface_listener = {
- surface_handle_enter,
- surface_handle_leave
-};
-
-static void
destroy_surfaces (GstGLWindowWaylandEGL * window_egl)
{
if (window_egl->window.subsurface) {
window_egl->window.queue);
}
- if (gst_gl_wl_display_roundtrip_queue (display->display,
- window_egl->window.queue) < 0) {
- GST_ERROR_OBJECT (window_egl,
- "Failed to perform a roundtrip on our wl_event_queue");
- }
-
if (window_egl->window.foreign_surface) {
/* (re)parent */
if (!display->subcompositor) {
gst_gl_window_wayland_egl_class_init (GstGLWindowWaylandEGLClass * klass)
{
GstGLWindowClass *window_class = (GstGLWindowClass *) klass;
- GObjectClass *gobject_class = (GObjectClass *) klass;
window_class->get_window_handle =
GST_DEBUG_FUNCPTR (gst_gl_window_wayland_egl_get_window_handle);
GST_DEBUG_FUNCPTR (gst_gl_window_wayland_egl_draw);
window_class->show = GST_DEBUG_FUNCPTR (gst_gl_window_wayland_egl_show);
window_class->draw = GST_DEBUG_FUNCPTR (gst_gl_window_wayland_egl_draw);
- window_class->run = GST_DEBUG_FUNCPTR (gst_gl_window_wayland_egl_run);
- window_class->quit = GST_DEBUG_FUNCPTR (gst_gl_window_wayland_egl_quit);
- window_class->send_message_async =
- GST_DEBUG_FUNCPTR (gst_gl_window_wayland_egl_send_message_async);
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);
-
- gobject_class->finalize = gst_gl_window_wayland_egl_finalize;
+ window_class->set_render_rectangle =
+ GST_DEBUG_FUNCPTR (gst_gl_window_wayland_egl_set_render_rectangle);
}
static void
gst_gl_window_wayland_egl_init (GstGLWindowWaylandEGL * window)
{
- window->main_context = g_main_context_new ();
- window->loop = g_main_loop_new (window->main_context, FALSE);
-}
-
-static void
-gst_gl_window_wayland_egl_finalize (GObject * object)
-{
- GstGLWindowWaylandEGL *window_egl = GST_GL_WINDOW_WAYLAND_EGL (object);
-
- g_main_loop_unref (window_egl->loop);
- g_main_context_unref (window_egl->main_context);
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
}
/* Must be called in the gl thread */
GstGLWindowWaylandEGL *
-gst_gl_window_wayland_egl_new (void)
+gst_gl_window_wayland_egl_new (GstGLDisplay * display)
{
- GstGLWindowWaylandEGL *window;
+ if ((gst_gl_display_get_handle_type (display) & GST_GL_DISPLAY_TYPE_WAYLAND)
+ == 0)
+ /* we require a wayland display to create wayland surfaces */
+ return NULL;
GST_DEBUG ("creating Wayland EGL window");
- window = g_object_new (GST_GL_TYPE_WINDOW_WAYLAND_EGL, NULL);
-
- return window;
+ return g_object_new (GST_GL_TYPE_WINDOW_WAYLAND_EGL, NULL);
}
static void
g_source_destroy (window_egl->wl_source);
g_source_unref (window_egl->wl_source);
window_egl->wl_source = NULL;
+
+ GST_GL_WINDOW_CLASS (parent_class)->close (window);
}
static gboolean
if (!display->display) {
g_set_error (error, GST_GL_WINDOW_ERROR,
GST_GL_WINDOW_ERROR_RESOURCE_UNAVAILABLE,
- "Failed to retreive Wayland display");
+ "Failed to retrieve Wayland display");
return FALSE;
}
window_egl->window.queue = wl_display_create_queue (display->display);
- wl_display_roundtrip (display->display);
-
- create_surfaces (window_egl);
-
window_egl->wl_source = wayland_event_source_new (display->display,
window_egl->window.queue);
- g_source_attach (window_egl->wl_source, window_egl->main_context);
-
- return TRUE;
-}
-
-static void
-gst_gl_window_wayland_egl_run (GstGLWindow * window)
-{
- GstGLWindowWaylandEGL *window_egl;
-
- window_egl = GST_GL_WINDOW_WAYLAND_EGL (window);
-
- GST_LOG ("starting main loop");
- g_main_loop_run (window_egl->loop);
- GST_LOG ("exiting main loop");
-}
-
-static void
-gst_gl_window_wayland_egl_quit (GstGLWindow * window)
-{
- GstGLWindowWaylandEGL *window_egl;
-
- window_egl = GST_GL_WINDOW_WAYLAND_EGL (window);
-
- GST_LOG ("sending quit");
-
- g_main_loop_quit (window_egl->loop);
-
- GST_LOG ("quit sent");
-}
-
-typedef struct _GstGLMessage
-{
- GstGLWindowCB callback;
- gpointer data;
- GDestroyNotify destroy;
-} GstGLMessage;
-
-static gboolean
-_run_message (GstGLMessage * message)
-{
- if (message->callback)
- message->callback (message->data);
-
- if (message->destroy)
- message->destroy (message->data);
-
- g_slice_free (GstGLMessage, message);
-
- return FALSE;
-}
-
-static void
-gst_gl_window_wayland_egl_send_message_async (GstGLWindow * window,
- GstGLWindowCB callback, gpointer data, GDestroyNotify destroy)
-{
- GstGLWindowWaylandEGL *window_egl;
- GstGLMessage *message;
-
- window_egl = GST_GL_WINDOW_WAYLAND_EGL (window);
- message = g_slice_new (GstGLMessage);
+ if (!GST_GL_WINDOW_CLASS (parent_class)->open (window, error))
+ return FALSE;
- message->callback = callback;
- message->data = data;
- message->destroy = destroy;
+ g_source_attach (window_egl->wl_source, g_main_context_get_thread_default ());
- g_main_context_invoke (window_egl->main_context, (GSourceFunc) _run_message,
- message);
+ return TRUE;
}
void
create_surfaces (window_egl);
+ if (window_egl->window.subsurface)
+ wl_subsurface_set_desync (window_egl->window.subsurface);
+
if (window->draw)
window->draw (window->draw_data);
gst_gl_window_send_message (window, (GstGLWindowCB) draw_cb, window);
}
+struct SetRenderRectangle
+{
+ GstGLWindowWaylandEGL *window_egl;
+ GstVideoRectangle rect;
+};
+
+static void
+_free_set_render_rectangle (struct SetRenderRectangle *render)
+{
+ if (render) {
+ if (render->window_egl)
+ gst_object_unref (render->window_egl);
+ g_free (render);
+ }
+}
+
+static void
+_set_render_rectangle (gpointer data)
+{
+ struct SetRenderRectangle *render = data;
+
+ GST_LOG_OBJECT (render->window_egl, "setting render rectangle %i,%i+%ix%i",
+ render->rect.x, render->rect.y, render->rect.w, render->rect.h);
+
+ if (render->window_egl->window.subsurface) {
+ wl_subsurface_set_sync (render->window_egl->window.subsurface);
+ wl_subsurface_set_position (render->window_egl->window.subsurface,
+ render->rect.x, render->rect.y);
+ render->window_egl->window.window_x = render->rect.x;
+ render->window_egl->window.window_y = render->rect.y;
+ }
+
+ window_resize (render->window_egl, render->rect.w, render->rect.h);
+}
+
+static gboolean
+gst_gl_window_wayland_egl_set_render_rectangle (GstGLWindow * window,
+ gint x, gint y, gint width, gint height)
+{
+ GstGLWindowWaylandEGL *window_egl = GST_GL_WINDOW_WAYLAND_EGL (window);
+ struct SetRenderRectangle *render;
+
+ render = g_new0 (struct SetRenderRectangle, 1);
+ render->window_egl = gst_object_ref (window_egl);
+ render->rect.x = x;
+ render->rect.y = y;
+ render->rect.w = width;
+ render->rect.h = height;
+
+ gst_gl_window_send_message_async (window,
+ (GstGLWindowCB) _set_render_rectangle, render,
+ (GDestroyNotify) _free_set_render_rectangle);
+
+ return TRUE;
+}
+
static guintptr
gst_gl_window_wayland_egl_get_display (GstGLWindow * window)
{