static void draw_cb (gpointer data) { GstGLWindowWaylandEGL *window_egl = data; GstGLWindow *window = GST_GL_WINDOW (window_egl); GstGLContext *context = gst_gl_window_get_context (window); GstGLContextClass *context_class = GST_GL_CONTEXT_GET_CLASS (context); create_surfaces (window_egl); if (window_egl->window.subsurface) wl_subsurface_set_desync (window_egl->window.subsurface); if (window->queue_resize) { guint width, height; gst_gl_window_get_surface_dimensions (window, &width, &height); gst_gl_window_resize (window, width, height); } if (window->draw) window->draw (window->draw_data); context_class->swap_buffers (context); if (window_egl->window.subsurface) wl_subsurface_set_desync (window_egl->window.subsurface); gst_object_unref (context); }
void gst_wl_window_render (GstWlWindow * window, GstWlBuffer * buffer, const GstVideoInfo * info) { if (G_UNLIKELY (info)) { window->video_width = gst_util_uint64_scale_int_round (info->width, info->par_n, info->par_d); window->video_height = info->height; wl_subsurface_set_sync (window->video_subsurface); gst_wl_window_resize_video_surface (window, FALSE); gst_wl_window_set_opaque (window, info); } if (G_LIKELY (buffer)) gst_wl_buffer_attach (buffer, window->video_surface_wrapper); else wl_surface_attach (window->video_surface_wrapper, NULL, 0, 0); wl_surface_damage (window->video_surface_wrapper, 0, 0, window->video_rectangle.w, window->video_rectangle.h); wl_surface_commit (window->video_surface_wrapper); if (G_UNLIKELY (info)) { /* commit also the parent (area_surface) in order to change * the position of the video_subsurface */ wl_surface_damage (window->area_surface_wrapper, 0, 0, window->render_rectangle.w, window->render_rectangle.h); wl_surface_commit (window->area_surface_wrapper); wl_subsurface_set_desync (window->video_subsurface); } wl_display_flush (window->display->display); }
void gst_wl_window_set_render_rectangle (GstWlWindow * window, gint x, gint y, gint w, gint h) { g_return_if_fail (window != NULL); window->render_rectangle.x = x; window->render_rectangle.y = y; window->render_rectangle.w = w; window->render_rectangle.h = h; /* position the area inside the parent - needs a parent commit to apply */ if (window->area_subsurface) wl_subsurface_set_position (window->area_subsurface, x, y); /* change the size of the area */ if (window->area_viewport) wp_viewport_set_destination (window->area_viewport, w, h); gst_wl_window_update_borders (window); if (window->video_width != 0) { wl_subsurface_set_sync (window->video_subsurface); gst_wl_window_resize_video_surface (window, TRUE); } wl_surface_damage (window->area_surface_wrapper, 0, 0, w, h); wl_surface_commit (window->area_surface_wrapper); if (window->video_width != 0) wl_subsurface_set_desync (window->video_subsurface); }
bool WaylandEGLContext::attach (GtkWidget *widget) { GdkWindow *window = gtk_widget_get_window (widget); if (!GDK_IS_WAYLAND_WINDOW (window)) return false; gdk_window = window; gdk_window_get_geometry (gdk_window, &x, &y, &width, &height); display = gdk_wayland_display_get_wl_display (gdk_window_get_display (gdk_window)); parent = gdk_wayland_window_get_wl_surface (gdk_window); registry = wl_display_get_registry (display); wl_registry_add_listener (registry, &wl_registry_listener, this); wl_display_roundtrip (display); if (!compositor || !subcompositor) return false; child = wl_compositor_create_surface (compositor); region = wl_compositor_create_region (compositor); subsurface = wl_subcompositor_get_subsurface (subcompositor, child, parent); wl_surface_set_input_region (child, region); wl_subsurface_set_desync (subsurface); wl_subsurface_set_position (subsurface, x, y); return true; }
GstWlWindow * gst_wl_window_new_in_surface (GstWlDisplay * display, struct wl_surface * parent) { GstWlWindow *window; window = gst_wl_window_new_internal (display, wl_compositor_create_surface (display->compositor)); window->subsurface = wl_subcompositor_get_subsurface (display->subcompositor, window->surface, parent); wl_subsurface_set_desync (window->subsurface); return window; }
GstWlWindow * gst_wl_window_new_in_surface (GstWlDisplay * display, struct wl_surface * parent, GMutex * render_lock) { GstWlWindow *window; window = gst_wl_window_new_internal (display, render_lock); /* embed in parent */ window->area_subsurface = wl_subcompositor_get_subsurface (display->subcompositor, window->area_surface, parent); wl_subsurface_set_desync (window->area_subsurface); return window; }
static GstWlWindow * gst_wl_window_new_internal (GstWlDisplay * display, GMutex * render_lock) { GstWlWindow *window; struct wl_region *region; window = g_object_new (GST_TYPE_WL_WINDOW, NULL); window->display = g_object_ref (display); window->render_lock = render_lock; window->area_surface = wl_compositor_create_surface (display->compositor); window->video_surface = wl_compositor_create_surface (display->compositor); window->area_surface_wrapper = wl_proxy_create_wrapper (window->area_surface); window->video_surface_wrapper = wl_proxy_create_wrapper (window->video_surface); wl_proxy_set_queue ((struct wl_proxy *) window->area_surface_wrapper, display->queue); wl_proxy_set_queue ((struct wl_proxy *) window->video_surface_wrapper, display->queue); /* embed video_surface in area_surface */ window->video_subsurface = wl_subcompositor_get_subsurface (display->subcompositor, window->video_surface, window->area_surface); wl_subsurface_set_desync (window->video_subsurface); if (display->viewporter) { window->area_viewport = wp_viewporter_get_viewport (display->viewporter, window->area_surface); window->video_viewport = wp_viewporter_get_viewport (display->viewporter, window->video_surface); } /* do not accept input */ region = wl_compositor_create_region (display->compositor); wl_surface_set_input_region (window->area_surface, region); wl_region_destroy (region); region = wl_compositor_create_region (display->compositor); wl_surface_set_input_region (window->video_surface, region); wl_region_destroy (region); return window; }
static void gst_wayland_sink_end_geometry_change (GstWaylandVideo * video) { GstWaylandSink *sink = GST_WAYLAND_SINK (video); g_return_if_fail (sink != NULL); g_mutex_lock (&sink->render_lock); if (!sink->window || !sink->window->area_subsurface) { g_mutex_unlock (&sink->render_lock); GST_INFO_OBJECT (sink, "end_geometry_change called without window, ignoring"); return; } wl_subsurface_set_desync (sink->window->area_subsurface); g_mutex_unlock (&sink->render_lock); }
static void create_surfaces (GstGLWindowWaylandEGL * window_egl) { GstGLDisplayWayland *display = GST_GL_DISPLAY_WAYLAND (GST_GL_WINDOW (window_egl)->display); gint width, height; if (!window_egl->window.surface) { window_egl->window.surface = wl_compositor_create_surface (display->compositor); if (window_egl->window.queue) wl_proxy_set_queue ((struct wl_proxy *) window_egl->window.surface, window_egl->window.queue); } if (window_egl->window.foreign_surface) { /* (re)parent */ if (!display->subcompositor) { GST_ERROR_OBJECT (window_egl, "Wayland server does not support subsurfaces"); window_egl->window.foreign_surface = NULL; goto shell_window; } if (!window_egl->window.subsurface) { window_egl->window.subsurface = wl_subcompositor_get_subsurface (display->subcompositor, window_egl->window.surface, window_egl->window.foreign_surface); if (window_egl->window.queue) wl_proxy_set_queue ((struct wl_proxy *) window_egl->window.subsurface, window_egl->window.queue); wl_subsurface_set_position (window_egl->window.subsurface, window_egl->window.window_x, window_egl->window.window_y); wl_subsurface_set_desync (window_egl->window.subsurface); } } else { shell_window: if (!window_egl->window.shell_surface) { window_egl->window.shell_surface = wl_shell_get_shell_surface (display->shell, window_egl->window.surface); if (window_egl->window.queue) wl_proxy_set_queue ((struct wl_proxy *) window_egl->window. shell_surface, window_egl->window.queue); wl_shell_surface_add_listener (window_egl->window.shell_surface, &shell_surface_listener, window_egl); wl_shell_surface_set_title (window_egl->window.shell_surface, "OpenGL Renderer"); wl_shell_surface_set_toplevel (window_egl->window.shell_surface); } } if (window_egl->window.window_width > 0) width = window_egl->window.window_width; else width = 320; window_egl->window.window_width = width; if (window_egl->window.window_height > 0) height = window_egl->window.window_height; else height = 240; window_egl->window.window_height = height; if (!window_egl->window.native) { gst_gl_window_resize (GST_GL_WINDOW (window_egl), width, height); window_egl->window.native = wl_egl_window_create (window_egl->window.surface, width, height); if (window_egl->window.queue) wl_proxy_set_queue ((struct wl_proxy *) window_egl->window.native, window_egl->window.queue); } }
static GstWlWindow * gst_wl_window_new_internal (GstWlDisplay * display) { GstWlWindow *window; GstVideoInfo info; GstBuffer *buf; GstMapInfo mapinfo; struct wl_buffer *wlbuf; GstWlBuffer *gwlbuf; struct wl_region *region; window = g_object_new (GST_TYPE_WL_WINDOW, NULL); window->display = g_object_ref (display); window->area_surface = wl_compositor_create_surface (display->compositor); window->video_surface = wl_compositor_create_surface (display->compositor); wl_proxy_set_queue ((struct wl_proxy *) window->area_surface, display->queue); wl_proxy_set_queue ((struct wl_proxy *) window->video_surface, display->queue); /* embed video_surface in area_surface */ window->video_subsurface = wl_subcompositor_get_subsurface (display->subcompositor, window->video_surface, window->area_surface); wl_subsurface_set_desync (window->video_subsurface); window->area_viewport = wl_scaler_get_viewport (display->scaler, window->area_surface); window->video_viewport = wl_scaler_get_viewport (display->scaler, window->video_surface); /* draw the area_subsurface */ gst_video_info_set_format (&info, /* we want WL_SHM_FORMAT_XRGB8888 */ #if G_BYTE_ORDER == G_BIG_ENDIAN GST_VIDEO_FORMAT_xRGB, #else GST_VIDEO_FORMAT_BGRx, #endif 1, 1); buf = gst_buffer_new_allocate (gst_wl_shm_allocator_get (), info.size, NULL); gst_buffer_map (buf, &mapinfo, GST_MAP_WRITE); *((guint32 *) mapinfo.data) = 0; /* paint it black */ gst_buffer_unmap (buf, &mapinfo); wlbuf = gst_wl_shm_memory_construct_wl_buffer (gst_buffer_peek_memory (buf, 0), display, &info); gwlbuf = gst_buffer_add_wl_buffer (buf, wlbuf, display); gst_wl_buffer_attach (gwlbuf, window->area_surface); /* at this point, the GstWlBuffer keeps the buffer * alive and will free it on wl_buffer::release */ gst_buffer_unref (buf); /* do not accept input */ region = wl_compositor_create_region (display->compositor); wl_surface_set_input_region (window->area_surface, region); wl_region_destroy (region); region = wl_compositor_create_region (display->compositor); wl_surface_set_input_region (window->video_surface, region); wl_region_destroy (region); return window; }