1From 499e9f7b9caa1e47194f8043d607f71eef2248bb Mon Sep 17 00:00:00 2001
2From: Jeffy Chen <jeffy.chen@rock-chips.com>
3Date: Fri, 5 Aug 2022 11:39:00 +0800
4Subject: [PATCH 36/36] waylandsink: Support transparent video
5
6Tested with transparent png picture.
7
8Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
9---
10 ext/wayland/wlwindow.c | 32 ++++++++++++++++++++++----------
11 ext/wayland/wlwindow.h |  3 +++
12 2 files changed, 25 insertions(+), 10 deletions(-)
13
14diff --git a/ext/wayland/wlwindow.c b/ext/wayland/wlwindow.c
15index ba1046a..330579f 100644
16--- a/ext/wayland/wlwindow.c
17+++ b/ext/wayland/wlwindow.c
18@@ -528,17 +528,19 @@ gst_wl_window_resize_video_surface (GstWlWindow * window, gboolean commit)
19 }
20
21 static void
22-gst_wl_window_set_opaque (GstWlWindow * window, const GstVideoInfo * info)
23+gst_wl_window_set_opaque (GstWlWindow * window)
24 {
25   struct wl_region *region;
26
27-  /* Set area opaque */
28-  region = wl_compositor_create_region (window->display->compositor);
29-  wl_region_add (region, 0, 0, G_MAXINT32, G_MAXINT32);
30-  wl_surface_set_opaque_region (window->area_surface, region);
31-  wl_region_destroy (region);
32+  if (window->area_opaque) {
33+    /* Set area opaque */
34+    region = wl_compositor_create_region (window->display->compositor);
35+    wl_region_add (region, 0, 0, G_MAXINT32, G_MAXINT32);
36+    wl_surface_set_opaque_region (window->area_surface, region);
37+    wl_region_destroy (region);
38+  }
39
40-  if (!GST_VIDEO_INFO_HAS_ALPHA (info)) {
41+  if (window->video_opaque) {
42     /* Set video opaque */
43     region = wl_compositor_create_region (window->display->compositor);
44     wl_region_add (region, 0, 0, G_MAXINT32, G_MAXINT32);
45@@ -554,10 +556,15 @@ gst_wl_window_render (GstWlWindow * window, GstWlBuffer * buffer,
46   if (G_UNLIKELY (info)) {
47     window->video_width = info->width;
48     window->video_height = info->height;
49+    window->video_opaque = !GST_VIDEO_INFO_HAS_ALPHA (info);
50+    window->area_opaque = window->video_opaque;
51+
52+    if (g_getenv ("WAYLANDSINK_FORCE_OPAQUE"))
53+      window->area_opaque = window->video_opaque = TRUE;
54
55     wl_subsurface_set_sync (window->video_subsurface);
56     gst_wl_window_resize_video_surface (window, FALSE);
57-    gst_wl_window_set_opaque (window, info);
58+    gst_wl_window_set_opaque (window);
59   } else if (window->crop_dirty) {
60     gst_wl_window_resize_video_surface (window, FALSE);
61   }
62@@ -624,8 +631,13 @@ gst_wl_window_update_borders (GstWlWindow * window)
63     height = window->render_rectangle.h;
64   }
65
66-  /* we want WL_SHM_FORMAT_XRGB8888 */
67-  format = GST_VIDEO_FORMAT_BGRx;
68+  if (window->area_opaque) {
69+    /* we want WL_SHM_FORMAT_XRGB8888 */
70+    format = GST_VIDEO_FORMAT_BGRx;
71+  } else {
72+    /* we want WL_SHM_FORMAT_ARGB8888 */
73+    format = GST_VIDEO_FORMAT_BGRA;
74+  }
75
76   /* draw the area_subsurface */
77   gst_video_info_set_format (&info, format, width, height);
78diff --git a/ext/wayland/wlwindow.h b/ext/wayland/wlwindow.h
79index 672e15a..66b69f4 100644
80--- a/ext/wayland/wlwindow.h
81+++ b/ext/wayland/wlwindow.h
82@@ -77,6 +77,9 @@ struct _GstWlWindow
83   gint crop_x, crop_y, crop_w, crop_h;
84   gboolean crop_dirty;
85
86+  gboolean video_opaque;
87+  gboolean area_opaque;
88+
89   /* when this is not set both the area_surface and the video_surface are not
90    * visible and certain steps should be skipped */
91   gboolean is_area_surface_mapped;
92--
932.20.1
94
95