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 gboolean gst_mfx_window_wayland_create (GstMfxWindow * window, guint * width, guint * height) { GstMfxWindowWaylandPrivate *const priv = GST_MFX_WINDOW_WAYLAND_GET_PRIVATE (window); GstMfxDisplayWaylandPrivate *const priv_display = GST_MFX_DISPLAY_WAYLAND_GET_PRIVATE (GST_MFX_WINDOW_DISPLAY (window)); struct wl_display *const wl_display = GST_MFX_DISPLAY_HANDLE (GST_MFX_WINDOW_DISPLAY (window)); GError *err = NULL; GST_DEBUG ("create window, size %ux%u", *width, *height); g_return_val_if_fail (priv_display->compositor != NULL, FALSE); g_return_val_if_fail (priv_display->shell != NULL, FALSE); GST_MFX_DISPLAY_LOCK (GST_MFX_WINDOW_DISPLAY (window)); priv->event_queue = wl_display_create_queue (wl_display); GST_MFX_DISPLAY_UNLOCK (GST_MFX_WINDOW_DISPLAY (window)); if (!priv->event_queue) return FALSE; GST_MFX_DISPLAY_LOCK (GST_MFX_WINDOW_DISPLAY (window)); priv->surface = wl_compositor_create_surface (priv_display->compositor); GST_MFX_DISPLAY_UNLOCK (GST_MFX_WINDOW_DISPLAY (window)); if (!priv->surface) return FALSE; wl_proxy_set_queue ((struct wl_proxy *) priv->surface, priv->event_queue); GST_MFX_DISPLAY_LOCK (GST_MFX_WINDOW_DISPLAY (window)); priv->shell_surface = wl_shell_get_shell_surface (priv_display->shell, priv->surface); GST_MFX_DISPLAY_UNLOCK (GST_MFX_WINDOW_DISPLAY (window)); if (!priv->shell_surface) return FALSE; wl_proxy_set_queue ((struct wl_proxy *) priv->shell_surface, priv->event_queue); wl_shell_surface_add_listener (priv->shell_surface, &shell_surface_listener, window); wl_shell_surface_set_toplevel (priv->shell_surface); #ifdef USE_WESTON_4_0 if (priv_display->viewporter) { GST_MFX_DISPLAY_LOCK (GST_MFX_WINDOW_DISPLAY (window)); priv->wp_viewport = wp_viewporter_get_viewport (priv_display->viewporter, priv->surface); GST_MFX_DISPLAY_UNLOCK (GST_MFX_WINDOW_DISPLAY (window)); } #else if (priv_display->scaler) { GST_MFX_DISPLAY_LOCK (GST_MFX_WINDOW_DISPLAY (window)); priv->viewport = wl_scaler_get_viewport (priv_display->scaler, priv->surface); GST_MFX_DISPLAY_UNLOCK (GST_MFX_WINDOW_DISPLAY (window)); } #endif priv->poll = gst_poll_new (TRUE); gst_poll_fd_init (&priv->pollfd); if (priv->fullscreen_on_show) gst_mfx_window_wayland_set_fullscreen (window, TRUE); #ifdef USE_EGL if (gst_mfx_display_has_opengl (GST_MFX_WINDOW_DISPLAY (window))) { priv->egl_window = wl_egl_window_create (priv->surface, *width, *height); if (!priv->egl_window) return FALSE; GST_MFX_WINDOW_ID (window) = GPOINTER_TO_INT(priv->egl_window); } #endif priv->thread = g_thread_try_new ("wayland-thread", gst_mfx_window_wayland_thread_run, window, &err); if (err) return FALSE; priv->is_shown = TRUE; return TRUE; }
static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg, video_format_t *fmtp, vlc_video_context *context) { if (cfg->window->type != VOUT_WINDOW_TYPE_WAYLAND) return VLC_EGENERIC; vout_display_sys_t *sys = malloc(sizeof (*sys)); if (unlikely(sys == NULL)) return VLC_ENOMEM; vd->sys = sys; sys->embed = NULL; sys->eventq = NULL; sys->shm = NULL; sys->viewporter = NULL; sys->active_buffers = 0; sys->display_width = cfg->display.width; sys->display_height = cfg->display.height; sys->use_buffer_transform = false; /* Get window */ sys->embed = cfg->window; assert(sys->embed != NULL); struct wl_display *display = sys->embed->display.wl; sys->eventq = wl_display_create_queue(display); if (sys->eventq == NULL) goto error; struct wl_registry *registry = wl_display_get_registry(display); if (registry == NULL) goto error; wl_proxy_set_queue((struct wl_proxy *)registry, sys->eventq); wl_registry_add_listener(registry, ®istry_cbs, vd); wl_display_roundtrip_queue(display, sys->eventq); wl_registry_destroy(registry); if (sys->shm == NULL) goto error; wl_shm_add_listener(sys->shm, &shm_cbs, vd); wl_display_roundtrip_queue(display, sys->eventq); struct wl_surface *surface = sys->embed->handle.wl; if (sys->viewporter != NULL) sys->viewport = wp_viewporter_get_viewport(sys->viewporter, surface); else sys->viewport = NULL; /* Determine our pixel format */ static const enum wl_output_transform transforms[8] = { [ORIENT_TOP_LEFT] = WL_OUTPUT_TRANSFORM_NORMAL, [ORIENT_TOP_RIGHT] = WL_OUTPUT_TRANSFORM_FLIPPED, [ORIENT_BOTTOM_LEFT] = WL_OUTPUT_TRANSFORM_FLIPPED_180, [ORIENT_BOTTOM_RIGHT] = WL_OUTPUT_TRANSFORM_180, [ORIENT_LEFT_TOP] = WL_OUTPUT_TRANSFORM_FLIPPED_270, [ORIENT_LEFT_BOTTOM] = WL_OUTPUT_TRANSFORM_90, [ORIENT_RIGHT_TOP] = WL_OUTPUT_TRANSFORM_270, [ORIENT_RIGHT_BOTTOM] = WL_OUTPUT_TRANSFORM_FLIPPED_90, };