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);
}
Beispiel #2
0
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);
}
Beispiel #3
0
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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
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;
}
Beispiel #7
0
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);
  }
}
Beispiel #10
0
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;
}