]> git.sesse.net Git - kdenlive/blobdiff - src/widgets/videoglwidget.cpp
Fix jittering issues when sending GL textures cross-thread.
[kdenlive] / src / widgets / videoglwidget.cpp
index a37d529d79e50f17a9e3cfdacc362eef80820c48..3c62742e8072380fc3d820795055a7390d363a70 100644 (file)
 #include <GL/glu.h>
 #endif
 #include "widgets/videoglwidget.h"
+extern "C" {
+GLAPI GLenum APIENTRY glClientWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout);
+}
+#include <mlt++/Mlt.h>
 
 #ifndef GL_TEXTURE_RECTANGLE_EXT
 #define GL_TEXTURE_RECTANGLE_EXT GL_TEXTURE_RECTANGLE_NV
@@ -40,7 +44,8 @@ VideoGLWidget::VideoGLWidget(QWidget *parent, QGLWidget *share)
     , m_image_width(0)
     , m_image_height(0)
     , m_texture(0)
-    , m_other_texture(0)
+    , m_frame(NULL)
+    , m_frame_texture(0)
     , m_display_ratio(4.0 / 3.0)
     , m_backgroundColor(Qt::gray)
 {  
@@ -53,6 +58,7 @@ VideoGLWidget::~VideoGLWidget()
     makeCurrent();
     if (m_texture)
         glDeleteTextures(1, &m_texture);
+    // m_frame will be cleaned up when the profile is closed by Render.
 }
 
 QSize VideoGLWidget::minimumSizeHint() const
@@ -147,12 +153,12 @@ void VideoGLWidget::paintGL()
         glEnd();
         glDisable(GL_TEXTURE_RECTANGLE_EXT);
     }
-    if (m_other_texture) {
+    if (m_frame_texture) {
 #ifdef Q_WS_MAC
                glClear(GL_COLOR_BUFFER_BIT);
 #endif
         glEnable(GL_TEXTURE_2D);
-        glBindTexture(GL_TEXTURE_2D, m_other_texture);
+        glBindTexture(GL_TEXTURE_2D, m_frame_texture);
         glBegin(GL_QUADS);
         glTexCoord2i(0, 0);
         glVertex2i(x, y);
@@ -174,7 +180,9 @@ void VideoGLWidget::showImage(const QImage &image)
     makeCurrent();
     if (m_texture)
         glDeleteTextures(1, &m_texture);
-    m_other_texture = 0;
+    delete m_frame;
+    m_frame = NULL;
+    m_frame_texture = 0;
 
     glPixelStorei(GL_UNPACK_ROW_LENGTH, m_image_width);
     glGenTextures(1, &m_texture);
@@ -186,14 +194,18 @@ void VideoGLWidget::showImage(const QImage &image)
     updateGL();
 }
 
-void VideoGLWidget::showImage(GLuint texnum)
+void VideoGLWidget::showImage(Mlt::Frame* frame, GLuint texnum)
 {
     makeCurrent();
+    GLsync sync = (GLsync) frame->get("movit.convert.fence");
+    glClientWaitSync(sync, 0, GL_TIMEOUT_IGNORED);
     if (m_texture) {
         glDeleteTextures(1, &m_texture);
         m_texture = 0;
     }
-    m_other_texture = texnum;
+    delete m_frame;
+    m_frame = frame;
+    m_frame_texture = texnum;
 
     updateGL();
 }