mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-20 00:31:13 +00:00
wpe: Move webview load waiting to WPEView
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>
This commit is contained in:
parent
248d2bb795
commit
8ef30a9ce5
2 changed files with 34 additions and 24 deletions
|
@ -76,8 +76,6 @@ WPEContextThread::WPEContextThread()
|
||||||
{
|
{
|
||||||
g_mutex_init(&threading.mutex);
|
g_mutex_init(&threading.mutex);
|
||||||
g_cond_init(&threading.cond);
|
g_cond_init(&threading.cond);
|
||||||
g_mutex_init(&threading.ready_mutex);
|
|
||||||
g_cond_init(&threading.ready_cond);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
GMutexHolder lock(threading.mutex);
|
GMutexHolder lock(threading.mutex);
|
||||||
|
@ -96,8 +94,6 @@ WPEContextThread::~WPEContextThread()
|
||||||
|
|
||||||
g_mutex_clear(&threading.mutex);
|
g_mutex_clear(&threading.mutex);
|
||||||
g_cond_clear(&threading.cond);
|
g_cond_clear(&threading.cond);
|
||||||
g_mutex_clear(&threading.ready_mutex);
|
|
||||||
g_cond_clear(&threading.ready_cond);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Function>
|
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)
|
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);
|
GST_DEBUG("context %p display %p, size (%d,%d)", context, display, width, height);
|
||||||
threading.ready = FALSE;
|
|
||||||
|
|
||||||
static std::once_flag s_loaderFlag;
|
static std::once_flag s_loaderFlag;
|
||||||
std::call_once(s_loaderFlag,
|
std::call_once(s_loaderFlag,
|
||||||
|
@ -190,24 +185,13 @@ WPEView* WPEContextThread::createWPEView(GstWpeSrc* src, GstGLContext* context,
|
||||||
|
|
||||||
if (view && view->hasUri()) {
|
if (view && view->hasUri()) {
|
||||||
GST_DEBUG("waiting load to finish");
|
GST_DEBUG("waiting load to finish");
|
||||||
GMutexHolder lock(threading.ready_mutex);
|
view->waitLoadCompletion();
|
||||||
while (!threading.ready)
|
|
||||||
g_cond_wait(&threading.ready_cond, &threading.ready_mutex);
|
|
||||||
GST_DEBUG("done");
|
GST_DEBUG("done");
|
||||||
}
|
}
|
||||||
|
|
||||||
return view;
|
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)
|
static gboolean s_loadFailed(WebKitWebView*, WebKitLoadEvent, gchar* failing_uri, GError* error, gpointer data)
|
||||||
{
|
{
|
||||||
GstWpeSrc* src = GST_WPE_SRC(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)
|
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);
|
g_mutex_init(&images_mutex);
|
||||||
if (context)
|
if (context)
|
||||||
gst.context = GST_GL_CONTEXT(gst_object_ref(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()
|
WPEView::~WPEView()
|
||||||
{
|
{
|
||||||
|
g_mutex_clear(&threading.ready_mutex);
|
||||||
|
g_cond_clear(&threading.ready_cond);
|
||||||
|
|
||||||
{
|
{
|
||||||
GMutexHolder lock(images_mutex);
|
GMutexHolder lock(images_mutex);
|
||||||
|
|
||||||
|
@ -319,6 +310,22 @@ WPEView::~WPEView()
|
||||||
g_mutex_clear(&images_mutex);
|
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* WPEView::image()
|
||||||
{
|
{
|
||||||
GstEGLImage* ret = nullptr;
|
GstEGLImage* ret = nullptr;
|
||||||
|
@ -481,7 +488,7 @@ void WPEView::handleExportedImage(gpointer image)
|
||||||
GST_TRACE("EGLImage %p wrapped in GstEGLImage %" GST_PTR_FORMAT, eglImage, gstImage);
|
GST_TRACE("EGLImage %p wrapped in GstEGLImage %" GST_PTR_FORMAT, eglImage, gstImage);
|
||||||
egl.pending = 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);
|
GMutexHolder lock(images_mutex);
|
||||||
GST_TRACE("SHM buffer %p wrapped in buffer %" GST_PTR_FORMAT, buffer, gstBuffer);
|
GST_TRACE("SHM buffer %p wrapped in buffer %" GST_PTR_FORMAT, buffer, gstBuffer);
|
||||||
shm.pending = gstBuffer;
|
shm.pending = gstBuffer;
|
||||||
s_view->notifyLoadFinished();
|
notifyLoadFinished();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -59,6 +59,7 @@ public:
|
||||||
/* Used by WPEContextThread */
|
/* Used by WPEContextThread */
|
||||||
bool hasUri() const { return webkit.uri; }
|
bool hasUri() const { return webkit.uri; }
|
||||||
void disconnectLoadFailedSignal();
|
void disconnectLoadFailedSignal();
|
||||||
|
void waitLoadCompletion();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void handleExportedImage(gpointer);
|
void handleExportedImage(gpointer);
|
||||||
|
@ -70,6 +71,7 @@ private:
|
||||||
struct wpe_view_backend* backend() const;
|
struct wpe_view_backend* backend() const;
|
||||||
void frameComplete();
|
void frameComplete();
|
||||||
void loadUriUnlocked(const gchar*);
|
void loadUriUnlocked(const gchar*);
|
||||||
|
void notifyLoadFinished();
|
||||||
|
|
||||||
void releaseImage(gpointer);
|
void releaseImage(gpointer);
|
||||||
#if ENABLE_SHM_BUFFER_SUPPORT
|
#if ENABLE_SHM_BUFFER_SUPPORT
|
||||||
|
@ -101,6 +103,12 @@ private:
|
||||||
|
|
||||||
bool m_isValid { false };
|
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,
|
// This mutex guards access to either egl or shm resources declared below,
|
||||||
// depending on the runtime behavior.
|
// depending on the runtime behavior.
|
||||||
GMutex images_mutex;
|
GMutex images_mutex;
|
||||||
|
@ -129,16 +137,11 @@ public:
|
||||||
template<typename Function>
|
template<typename Function>
|
||||||
void dispatch(Function);
|
void dispatch(Function);
|
||||||
|
|
||||||
void notifyLoadFinished();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static gpointer s_viewThread(gpointer);
|
static gpointer s_viewThread(gpointer);
|
||||||
struct {
|
struct {
|
||||||
GMutex mutex;
|
GMutex mutex;
|
||||||
GCond cond;
|
GCond cond;
|
||||||
GMutex ready_mutex;
|
|
||||||
GCond ready_cond;
|
|
||||||
gboolean ready;
|
|
||||||
GThread* thread { nullptr };
|
GThread* thread { nullptr };
|
||||||
} threading;
|
} threading;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue