VIGS/qt5: move swapBuffers to separate thread 95/25095/2
authorStanislav Vorobiov <s.vorobiov@samsung.com>
Tue, 29 Jul 2014 10:34:07 +0000 (14:34 +0400)
committerSeokYeon Hwang <syeon.hwang@samsung.com>
Wed, 30 Jul 2014 05:09:56 +0000 (22:09 -0700)
With some OpenGL implementations swapBuffers may take
considerable amount of time (up to 16ms - i.e. 60fps) to
complete. Since window rendering happens on vmexit
we move swapBuffers to separate thread in order not to
stall the guest

Change-Id: I92c9caee94709e656e842f8d9bc8258c25a9d453
Signed-off-by: Stanislav Vorobiov <s.vorobiov@samsung.com>
hw/vigs/vigs_gl_backend.c
tizen/src/ui/displaywidget.cpp
tizen/src/ui/displaywidget.h
tizen/src/ui/mainwindow.cpp
tizen/src/ui/mainwindow.h

index 8c79f8c9934bb8ff3440dec6cfccaa7d6e440995..f8c467de3e45f72ec3d6dc9e522e64f4c334f9b5 100644 (file)
@@ -1405,8 +1405,6 @@ static bool vigs_gl_backend_composite(struct vigs_surface *surface,
         vigs_gl_draw_dpy_tex_prog(gl_backend, 6);
     }
 
-    gl_backend->Finish();
-
     return false;
 }
 
index e92fd36ee362a11abba7078b0b251832bcbcf592..19150196ba1796e8bc1db9324db84227d25f815a 100644 (file)
@@ -54,11 +54,15 @@ void DisplayWidget::scale(int scale)
     repaint();
 }
 
+void DisplayWidget::paintEvent(QPaintEvent *event)
+{
+}
+
 void DisplayWidget::resizeEvent(QResizeEvent *event)
 {
     qDebug("resize display");
 
-    QGLWidget::resizeEvent(event); /* initializeGL */
+    //QGLWidget::resizeEvent(event); /* initializeGL */
 
     MainWindow *win = ((MainWindow *)this->parent()->parent());
     SkinLayout *layout = win->uiInfo->getLayout();
index 6bdf09ab04f69c23b16e57904a9ef6ca78275a05..312643181d23c9febb8bc9f119644022f725252c 100644 (file)
@@ -17,6 +17,7 @@ public:
 protected:
     void initializeGL();
 
+    void paintEvent(QPaintEvent *event);
     void resizeEvent(QResizeEvent *event);
 
     void mousePressEvent(QMouseEvent *event);
index 09c48b038e0752083b72e383a740e040c4ae24b8..b447e3549e56215011ef66791d3ea975261cd556 100644 (file)
@@ -12,6 +12,44 @@ extern "C" void shutdown_qemu_gracefully(void);
 QOpenGLContext *qt5GLContext = NULL;
 QSurfaceFormat qt5GLFormat;
 
+DisplaySwapper::DisplaySwapper(QGLContext* context, QObject* parent)
+: QObject(parent),
+  context(context),
+  swapping(false)
+{
+}
+
+void DisplaySwapper::lock()
+{
+    m.lock();
+
+    while (swapping) {
+        c.wait(&m);
+    }
+
+    m.unlock();
+}
+
+void DisplaySwapper::unlock()
+{
+    swapping = true;
+}
+
+void DisplaySwapper::swapBuffers()
+{
+    context->makeCurrent();
+    context->swapBuffers();
+    context->doneCurrent();
+
+    context->moveToThread(qApp->thread());
+
+    m.lock();
+    swapping = false;
+    m.unlock();
+
+    c.wakeAll();
+}
+
 MainWindow::MainWindow(UIInformation *uiInfo, QWidget *parent) :
     QWidget(parent)
 {
@@ -93,6 +131,14 @@ MainWindow::MainWindow(UIInformation *uiInfo, QWidget *parent) :
     setContextMenuPolicy(Qt::CustomContextMenu);
     connect(this, SIGNAL(customContextMenuRequested(const QPoint&)),
             SLOT(showContextMenu(const QPoint&)));
+
+    swapperThread = new QThread(this);
+
+    swapper = new DisplaySwapper(context);
+    swapper->moveToThread(swapperThread);
+    connect(swapperThread, &QThread::finished, swapper, &QObject::deleteLater);
+
+    swapperThread->start();
 }
 
 QLabel *MainWindow::getLabel()
@@ -103,10 +149,13 @@ QLabel *MainWindow::getLabel()
 void MainWindow::makeCurrent(bool value)
 {
     if (value) {
+        swapper->lock();
         display->makeCurrent();
     } else {
-        display->swapBuffers();
         display->doneCurrent();
+        swapper->unlock();
+        display->context()->moveToThread(swapperThread);
+        QMetaObject::invokeMethod(swapper, "swapBuffers", Qt::QueuedConnection);
     }
 }
 
@@ -170,6 +219,9 @@ void MainWindow::setRegion(QImage baseImage)
 MainWindow::~MainWindow()
 {
     qDebug("destory main window");
+
+    swapperThread->quit();
+    swapperThread->wait();
 }
 
 void MainWindow::closeEvent(QCloseEvent *event)
index 363b599dcfd3f3f179d83586973db07d638f54d8..83f04963a9913a1c3f061b95767ee9b2886f7a8a 100644 (file)
@@ -14,6 +14,26 @@ QT_BEGIN_NAMESPACE
 class QLabel;
 QT_END_NAMESPACE
 
+class DisplaySwapper : public QObject
+{
+    Q_OBJECT
+
+public:
+    DisplaySwapper(QGLContext* context, QObject* parent = 0);
+
+    void lock();
+    void unlock();
+
+public slots:
+    void swapBuffers();
+
+private:
+    QGLContext *context;
+    QMutex m;
+    QWaitCondition c;
+    bool swapping;
+};
+
 class MainWindow : public QWidget
 {
     Q_OBJECT
@@ -47,6 +67,8 @@ private:
     SkinView* skinView;
     DisplayWidget *display;
     SkinControllerView *conView;
+    QThread *swapperThread;
+    DisplaySwapper *swapper;
 };
 
 #endif // MAINWINDOW_H