wpe: Move webview load waiting to WPEView
authorPhilippe Normand <philn@igalia.com>
Thu, 10 Sep 2020 13:39:58 +0000 (14:39 +0100)
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Mon, 21 Sep 2020 16:39:57 +0000 (16:39 +0000)
As waiting for the load to be finished is specific to the WebView, it should be
done from our WPEView, not from the WPEContextThread. This fixes issues where
multiple wpesrc elements are created in sequence. Without this patch the first
view might receive erroneous buffer notifications.

Fixes #1386

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1568>

ext/wpe/WPEThreadedView.cpp
ext/wpe/WPEThreadedView.h

index bf888350f3f707690e22eaceb2222eafab3a9da9..797751738fe62785cdf4f35baf2781a015fae5d7 100644 (file)
@@ -76,8 +76,6 @@ WPEContextThread::WPEContextThread()
 {
     g_mutex_init(&threading.mutex);
     g_cond_init(&threading.cond);
-    g_mutex_init(&threading.ready_mutex);
-    g_cond_init(&threading.ready_cond);
 
     {
         GMutexHolder lock(threading.mutex);
@@ -96,8 +94,6 @@ WPEContextThread::~WPEContextThread()
 
     g_mutex_clear(&threading.mutex);
     g_cond_clear(&threading.cond);
-    g_mutex_clear(&threading.ready_mutex);
-    g_cond_clear(&threading.ready_cond);
 }
 
 template<typename Function>
@@ -167,7 +163,6 @@ gpointer WPEContextThread::s_viewThread(gpointer data)
 WPEView* WPEContextThread::createWPEView(GstWpeSrc* src, GstGLContext* context, GstGLDisplay* display, int width, int height)
 {
     GST_DEBUG("context %p display %p, size (%d,%d)", context, display, width, height);
-    threading.ready = FALSE;
 
     static std::once_flag s_loaderFlag;
     std::call_once(s_loaderFlag,
@@ -190,24 +185,13 @@ WPEView* WPEContextThread::createWPEView(GstWpeSrc* src, GstGLContext* context,
 
     if (view && view->hasUri()) {
         GST_DEBUG("waiting load to finish");
-        GMutexHolder lock(threading.ready_mutex);
-        while (!threading.ready)
-            g_cond_wait(&threading.ready_cond, &threading.ready_mutex);
+        view->waitLoadCompletion();
         GST_DEBUG("done");
     }
 
     return view;
 }
 
-void WPEContextThread::notifyLoadFinished()
-{
-    GMutexHolder lock(threading.ready_mutex);
-    if (!threading.ready) {
-        threading.ready = TRUE;
-        g_cond_signal(&threading.ready_cond);
-    }
-}
-
 static gboolean s_loadFailed(WebKitWebView*, WebKitLoadEvent, gchar* failing_uri, GError* error, gpointer data)
 {
     GstWpeSrc* src = GST_WPE_SRC(data);
@@ -223,6 +207,10 @@ static gboolean s_loadFailedWithTLSErrors(WebKitWebView*,  gchar* failing_uri, G
 
 WPEView::WPEView(WebKitWebContext* web_context, GstWpeSrc* src, GstGLContext* context, GstGLDisplay* display, int width, int height)
 {
+    g_mutex_init(&threading.ready_mutex);
+    g_cond_init(&threading.ready_cond);
+    threading.ready = FALSE;
+
     g_mutex_init(&images_mutex);
     if (context)
         gst.context = GST_GL_CONTEXT(gst_object_ref(context));
@@ -282,6 +270,9 @@ WPEView::WPEView(WebKitWebContext* web_context, GstWpeSrc* src, GstGLContext* co
 
 WPEView::~WPEView()
 {
+    g_mutex_clear(&threading.ready_mutex);
+    g_cond_clear(&threading.ready_cond);
+
     {
         GMutexHolder lock(images_mutex);
 
@@ -319,6 +310,22 @@ WPEView::~WPEView()
     g_mutex_clear(&images_mutex);
 }
 
+void WPEView::notifyLoadFinished()
+{
+    GMutexHolder lock(threading.ready_mutex);
+    if (!threading.ready) {
+        threading.ready = TRUE;
+        g_cond_signal(&threading.ready_cond);
+    }
+}
+
+void WPEView::waitLoadCompletion()
+{
+    GMutexHolder lock(threading.ready_mutex);
+    while (!threading.ready)
+        g_cond_wait(&threading.ready_cond, &threading.ready_mutex);
+}
+
 GstEGLImage* WPEView::image()
 {
     GstEGLImage* ret = nullptr;
@@ -481,7 +488,7 @@ void WPEView::handleExportedImage(gpointer image)
       GST_TRACE("EGLImage %p wrapped in GstEGLImage %" GST_PTR_FORMAT, eglImage, gstImage);
       egl.pending = gstImage;
 
-      s_view->notifyLoadFinished();
+      notifyLoadFinished();
     }
 }
 
@@ -538,7 +545,7 @@ void WPEView::handleExportedBuffer(struct wpe_fdo_shm_exported_buffer* buffer)
         GMutexHolder lock(images_mutex);
         GST_TRACE("SHM buffer %p wrapped in buffer %" GST_PTR_FORMAT, buffer, gstBuffer);
         shm.pending = gstBuffer;
-        s_view->notifyLoadFinished();
+        notifyLoadFinished();
     }
 }
 #endif
index 359e80ea94c9511d78389f93460326d43b44444a..c5633abc5e8d5aec1cc9a79a0b539f2a2935852c 100644 (file)
@@ -59,6 +59,7 @@ public:
     /*  Used by WPEContextThread */
     bool hasUri() const { return webkit.uri; }
     void disconnectLoadFailedSignal();
+    void waitLoadCompletion();
 
 protected:
     void handleExportedImage(gpointer);
@@ -70,6 +71,7 @@ private:
     struct wpe_view_backend* backend() const;
     void frameComplete();
     void loadUriUnlocked(const gchar*);
+    void notifyLoadFinished();
 
     void releaseImage(gpointer);
 #if ENABLE_SHM_BUFFER_SUPPORT
@@ -101,6 +103,12 @@ private:
 
     bool m_isValid { false };
 
+    struct {
+        GMutex ready_mutex;
+        GCond ready_cond;
+        gboolean ready;
+    } threading;
+
     // This mutex guards access to either egl or shm resources declared below,
     // depending on the runtime behavior.
     GMutex images_mutex;
@@ -129,16 +137,11 @@ public:
     template<typename Function>
     void dispatch(Function);
 
-    void notifyLoadFinished();
-
 private:
     static gpointer s_viewThread(gpointer);
     struct {
         GMutex mutex;
         GCond cond;
-        GMutex ready_mutex;
-        GCond ready_cond;
-        gboolean ready;
         GThread* thread { nullptr };
     } threading;