From: Stanislav Vorobiov Date: Tue, 29 Jul 2014 10:34:07 +0000 (+0400) Subject: VIGS/qt5: move swapBuffers to separate thread X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=25b0b814910ade4e1087b5836495c93fcf001ce6;p=sdk%2Femulator%2Fqemu.git VIGS/qt5: move swapBuffers to separate thread 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 --- diff --git a/hw/vigs/vigs_gl_backend.c b/hw/vigs/vigs_gl_backend.c index 8c79f8c993..f8c467de3e 100644 --- a/hw/vigs/vigs_gl_backend.c +++ b/hw/vigs/vigs_gl_backend.c @@ -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; } diff --git a/tizen/src/ui/displaywidget.cpp b/tizen/src/ui/displaywidget.cpp index e92fd36ee3..19150196ba 100644 --- a/tizen/src/ui/displaywidget.cpp +++ b/tizen/src/ui/displaywidget.cpp @@ -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(); diff --git a/tizen/src/ui/displaywidget.h b/tizen/src/ui/displaywidget.h index 6bdf09ab04..312643181d 100644 --- a/tizen/src/ui/displaywidget.h +++ b/tizen/src/ui/displaywidget.h @@ -17,6 +17,7 @@ public: protected: void initializeGL(); + void paintEvent(QPaintEvent *event); void resizeEvent(QResizeEvent *event); void mousePressEvent(QMouseEvent *event); diff --git a/tizen/src/ui/mainwindow.cpp b/tizen/src/ui/mainwindow.cpp index 09c48b038e..b447e3549e 100644 --- a/tizen/src/ui/mainwindow.cpp +++ b/tizen/src/ui/mainwindow.cpp @@ -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) diff --git a/tizen/src/ui/mainwindow.h b/tizen/src/ui/mainwindow.h index 363b599dcf..83f04963a9 100644 --- a/tizen/src/ui/mainwindow.h +++ b/tizen/src/ui/mainwindow.h @@ -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