qmlglsink: Schedule onSceneGrpahInitialized to execute on render thread
authorSergey Borovkov <sergey.borovkov@wireload.net>
Sun, 24 Jan 2016 14:40:37 +0000 (17:40 +0300)
committerMatthew Waters <matthew@centricular.com>
Mon, 22 Feb 2016 09:26:41 +0000 (20:26 +1100)
onSceneGraphInitialized() is called from non render thread currently when
scene graph is already initialized.

https://bugzilla.gnome.org/show_bug.cgi?id=761003

ext/qt/qtitem.cc
ext/qt/qtitem.h

index 9dc058a..648e0e8 100644 (file)
@@ -28,6 +28,7 @@
 #include "qtitem.h"
 #include "gstqsgtexture.h"
 
+#include <QtCore/QRunnable>
 #include <QtGui/QGuiApplication>
 #include <QtQuick/QQuickWindow>
 #include <QtQuick/QSGSimpleTextureNode>
@@ -99,6 +100,26 @@ struct _QtGLVideoItemPrivate
   GstGLContext *context;
 };
 
+class InitializeSceneGraph : public QRunnable
+{
+public:
+  InitializeSceneGraph(QtGLVideoItem *item);
+  void run();
+
+private:
+  QtGLVideoItem *item_;
+};
+
+InitializeSceneGraph::InitializeSceneGraph(QtGLVideoItem *item) :
+  item_(item)
+{
+}
+
+void InitializeSceneGraph::run()
+{
+  item_->onSceneGraphInitialized();
+}
+
 QtGLVideoItem::QtGLVideoItem()
 {
   QGuiApplication *app = dynamic_cast<QGuiApplication *> (QCoreApplication::instance ());
@@ -110,7 +131,7 @@ QtGLVideoItem::QtGLVideoItem()
     GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "qtglwidget", 0, "Qt GL Widget");
     g_once_init_leave (&_debug, 1);
   }
-
+  this->m_openGlContextInitialized = false;
   this->setFlag (QQuickItem::ItemHasContents, true);
 
   this->priv = g_new0 (QtGLVideoItemPrivate, 1);
@@ -188,6 +209,10 @@ QSGNode *
 QtGLVideoItem::updatePaintNode(QSGNode * oldNode,
     UpdatePaintNodeData * updatePaintNodeData)
 {
+  if (!m_openGlContextInitialized) {
+    return oldNode;
+  }
+
   QSGSimpleTextureNode *texNode = static_cast<QSGSimpleTextureNode *> (oldNode);
   GstVideoRectangle src, dst, result;
   GstQSGTexture *tex;
@@ -354,6 +379,7 @@ QtGLVideoItem::onSceneGraphInitialized ()
     } else {
       gst_gl_display_filter_gl_api (this->priv->display, gst_gl_context_get_gl_api (this->priv->other_context));
       gst_gl_context_activate (this->priv->other_context, FALSE);
+      m_openGlContextInitialized = true;
     }
   }
 
@@ -414,9 +440,9 @@ QtGLVideoItem::handleWindowChanged(QQuickWindow *win)
 {
   if (win) {
     if (win->isSceneGraphInitialized())
-      onSceneGraphInitialized();
+      win->scheduleRenderJob(new InitializeSceneGraph(this), QQuickWindow::BeforeSynchronizingStage);
     else
-         connect(win, SIGNAL(sceneGraphInitialized()), this, SLOT(onSceneGraphInitialized()), Qt::DirectConnection);
+      connect(win, SIGNAL(sceneGraphInitialized()), this, SLOT(onSceneGraphInitialized()), Qt::DirectConnection);
 
     connect(win, SIGNAL(sceneGraphInvalidated()), this, SLOT(onSceneGraphInvalidated()), Qt::DirectConnection);
   } else {
index 5a07634..ae23eff 100644 (file)
@@ -31,6 +31,8 @@
 
 typedef struct _QtGLVideoItemPrivate QtGLVideoItemPrivate;
 
+class InitializeSceneGraph;
+
 class QtGLVideoItem : public QQuickItem, protected QOpenGLFunctions
 {
     Q_OBJECT
@@ -55,10 +57,12 @@ protected:
     QSGNode * updatePaintNode (QSGNode * oldNode, UpdatePaintNodeData * updatePaintNodeData);
 
 private:
+    friend class InitializeSceneGraph;
     void setViewportSize(const QSize &size);
     void shareContext();
 
     QSize m_viewportSize;
+    bool m_openGlContextInitialized;
 };
 
 extern "C"