MMFMWK-7954 waylandsink: support linux-dmabuf version 3

waylandsink need support linux-dmabuf version 3
to enable modifier handle

upstream status: pending
https://bugzilla.gnome.org/show_bug.cgi?id=797071
diff --git a/ext/wayland/wldisplay.c b/ext/wayland/wldisplay.c
index 9b56922..a245fa1 100644
--- a/ext/wayland/wldisplay.c
+++ b/ext/wayland/wldisplay.c
@@ -46,6 +46,8 @@
 gst_wl_display_init (GstWlDisplay * self)
 {
   self->shm_formats = g_array_new (FALSE, FALSE, sizeof (uint32_t));
+  self->dmabuf_modifiers = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+                            NULL, (GDestroyNotify) g_array_unref);
   self->dmabuf_formats = g_array_new (FALSE, FALSE, sizeof (uint32_t));
   self->wl_fd_poll = gst_poll_new (TRUE);
   self->buffers = g_hash_table_new (g_direct_hash, g_direct_equal);
@@ -76,8 +78,10 @@
       (GHFunc) gst_wl_buffer_force_release_and_unref, NULL);
   g_hash_table_remove_all (self->buffers);
 
-  g_array_unref (self->shm_formats);
+  g_hash_table_remove_all (self->dmabuf_modifiers);
   g_array_unref (self->dmabuf_formats);
+
+  g_array_unref (self->shm_formats);
   gst_poll_free (self->wl_fd_poll);
   g_hash_table_unref (self->buffers);
   g_mutex_clear (&self->buffers_mutex);
@@ -167,14 +171,42 @@
 dmabuf_format (void *data, struct zwp_linux_dmabuf_v1 *zwp_linux_dmabuf,
     uint32_t format)
 {
-  GstWlDisplay *self = data;
+  /* this event has been deprecated */
+}
 
-  if (gst_wl_dmabuf_format_to_video_format (format) != GST_VIDEO_FORMAT_UNKNOWN)
-    g_array_append_val (self->dmabuf_formats, format);
+static void dmabuf_modifier(void *data,
+			 struct zwp_linux_dmabuf_v1 *zwp_linux_dmabuf_v1,
+			 uint32_t format,
+			 uint32_t modifier_hi,
+			 uint32_t modifier_lo)
+{
+  GstWlDisplay *self = data;
+  uint64_t modifier = ((uint64_t)modifier_hi << 32) | modifier_lo;
+
+  if (gst_wl_dmabuf_format_to_video_format (format) != GST_VIDEO_FORMAT_UNKNOWN) {
+    if (!g_hash_table_contains (self->dmabuf_modifiers, GUINT_TO_POINTER (format))){
+      GArray *modifiers = g_array_new (FALSE, FALSE, sizeof (uint64_t));
+      g_array_append_val (modifiers, modifier);
+      g_hash_table_insert (self->dmabuf_modifiers, GUINT_TO_POINTER (format), modifiers);
+
+      g_array_append_val (self->dmabuf_formats, format);
+    } else {
+      int i;
+      GArray *modifiers = g_hash_table_lookup (self->dmabuf_modifiers, GUINT_TO_POINTER (format));
+      for (i = 0; i < modifiers->len; i++) {
+        uint64_t mod = g_array_index (modifiers, uint64_t, i);
+        if (mod == modifier)
+         break;
+      }
+      if (i == modifiers->len)
+        g_array_append_val (modifiers, modifier);
+    }
+  }
 }
 
 static const struct zwp_linux_dmabuf_v1_listener dmabuf_listener = {
   dmabuf_format,
+  dmabuf_modifier
 };
 
 gboolean
@@ -293,7 +325,7 @@
         wl_registry_bind (registry, id, &wp_viewporter_interface, 1);
   } else if (g_strcmp0 (interface, "zwp_linux_dmabuf_v1") == 0) {
     self->dmabuf =
-        wl_registry_bind (registry, id, &zwp_linux_dmabuf_v1_interface, 1);
+        wl_registry_bind (registry, id, &zwp_linux_dmabuf_v1_interface, version);
     zwp_linux_dmabuf_v1_add_listener (self->dmabuf, &dmabuf_listener, self);
   } else if (g_strcmp0 (interface, "zwp_alpha_compositing_v1") == 0) {
     self->alpha_compositing =
diff --git a/ext/wayland/wldisplay.h b/ext/wayland/wldisplay.h
index 45ef293..83c45be 100644
--- a/ext/wayland/wldisplay.h
+++ b/ext/wayland/wldisplay.h
@@ -62,6 +62,7 @@
   struct zwp_hdr10_metadata_v1 *hdr10_metadata;
   GArray *shm_formats;
   GArray *dmabuf_formats;
+  GHashTable *dmabuf_modifiers;
 
   /* real display resolution */
   gint width, height;