diff options
author | Jinhyung Jo <jinhyung.jo@samsung.com> | 2016-11-09 15:52:27 +0900 |
---|---|---|
committer | SeokYeon Hwang <syeon.hwang@samsung.com> | 2016-12-02 17:31:25 +0900 |
commit | f6f9dabab4a3b1d2e19bd7fde47de8dafc131b46 (patch) | |
tree | 7dda6ec270ff1b4c02e98ead2bad9530d87a63a2 /tizen | |
parent | 9bd89b92f93eb1726e4bfc1bfafb278c2682ff06 (diff) | |
download | qemu-f6f9dabab4a3b1d2e19bd7fde47de8dafc131b46.tar.gz qemu-f6f9dabab4a3b1d2e19bd7fde47de8dafc131b46.tar.bz2 qemu-f6f9dabab4a3b1d2e19bd7fde47de8dafc131b46.zip |
display: fix blinking display issue with OpenGL 2.1
Use the texture arrays to avoid collisions.
The glBufferSubData function makes the display blink
with OpenGL verion 2.1 have no glMapBufferRange support.
The glMapBuffer function helps to solve this problem.
Use the Qt5 class API(QOpenGLShaderProgram) instead of the OpenGL API.
That's a little clearer and better to watch.
Use multiple buffering to avoid performance degration.
Change-Id: I819a52f7e0db5accded86b71c8a15fa1a9e65e28
Signed-off-by: Jinhyung Jo <jinhyung.jo@samsung.com>
Signed-off-by: SeokYeon Hwang <syeon.hwang@samsung.com>
Diffstat (limited to 'tizen')
-rw-r--r-- | tizen/src/ui/displayglwidget.cpp | 59 | ||||
-rw-r--r-- | tizen/src/ui/displayglwidget.h | 24 | ||||
-rw-r--r-- | tizen/src/ui/mainwindow.cpp | 4 | ||||
-rw-r--r-- | tizen/src/ui/mainwindow.h | 2 | ||||
-rw-r--r-- | tizen/src/ui/qt5_supplement.cpp | 4 |
5 files changed, 66 insertions, 27 deletions
diff --git a/tizen/src/ui/displayglwidget.cpp b/tizen/src/ui/displayglwidget.cpp index 0a9d06d26d..14aa91b935 100644 --- a/tizen/src/ui/displayglwidget.cpp +++ b/tizen/src/ui/displayglwidget.cpp @@ -212,20 +212,28 @@ DisplayGLWidget::DisplayGLWidget(QWidget *parent, this->maskQImage = displayForm->getMask().toImage(); this->maskTexture = 0; this->needScale = false; - this->dpyTexture = 0; this->mtTexture = 0; this->texProgram = NULL; this->scaleProgram = NULL; + this->next = NULL; + this->current = NULL; /* to be enable to drop events */ setAcceptDrops(true); } -void DisplayGLWidget::changedTexture(unsigned int id) +void DisplayGLWidget::changedTexture(struct dpy_item *item) { - if (dpyTexture != id) { - dpyTexture = id; + // wait while "next" is being updated since it is fast enough. + textureListMutex.lock(); + if (next) { + qemu_mutex_lock(&next->mutex); + next->available = true; + qemu_mutex_unlock(&next->mutex); } + next = item; + textureListMutex.unlock(); + this->update(); } @@ -247,8 +255,6 @@ void DisplayGLWidget::drawQuad(GLuint textureID, bool isMask) program->bind(); program->enableAttributeArray("vertCoord"); program->enableAttributeArray("texCoord"); - int vertCoordLoc = program->attributeLocation("vertCoord"); - int texCoordLoc = program->attributeLocation("texCoord"); program->setUniformValue("proj", mOrtho); if (needScale) { GLfloat texSize[2]; @@ -261,9 +267,8 @@ void DisplayGLWidget::drawQuad(GLuint textureID, bool isMask) mVBO->bind(); mVBO->write(0, mVertCoords, COORDS_SIZE); mVBO->write(COORDS_SIZE, mTexCoords, COORDS_SIZE); - mFuncs->glVertexAttribPointer(vertCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, 0); - mFuncs->glVertexAttribPointer(texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, - TO_VOIDP(COORDS_SIZE)); + program->setAttributeArray("vertCoord", GL_FLOAT, NULL, 2, 0); + program->setAttributeArray("texCoord", GL_FLOAT, TO_VOIDP(COORDS_SIZE), 2, 0); mVBO->release(); mFuncs->glDrawArrays(GL_TRIANGLES, 0, COORD_COUNT); @@ -314,8 +319,6 @@ void DisplayGLWidget::drawMultiTouchPoints() texProgram->bind(); texProgram->enableAttributeArray("vertCoord"); texProgram->enableAttributeArray("texCoord"); - int vertCoordLoc = texProgram->attributeLocation("vertCoord"); - int texCoordLoc = texProgram->attributeLocation("texCoord"); QMatrix4x4 mat; mat.ortho(0.0f, (float)width(), @@ -323,10 +326,10 @@ void DisplayGLWidget::drawMultiTouchPoints() -1.0f, 1.0f); texProgram->setUniformValue("proj", mat); texProgram->setUniformValue("brightness", 0.7f); - - mFuncs->glVertexAttribPointer(vertCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, 0); - mFuncs->glVertexAttribPointer(texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, - TO_VOIDP(pointList.count() * COORDS_SIZE)); + texProgram->setAttributeArray("vertCoord", GL_FLOAT, NULL, 2, 0); + texProgram->setAttributeArray("texCoord", GL_FLOAT, + TO_VOIDP(pointList.count() * COORDS_SIZE), + 2, 0); mVBO->release(); mFuncs->glDrawArrays(GL_TRIANGLES, 0, pointList.count() * COORD_COUNT); @@ -427,14 +430,14 @@ void DisplayGLWidget::initializeGL() (const void *)maskQImage.constBits()); mFuncs->glBindTexture(GL_TEXTURE_2D, curTexture); } + mFuncs->glDisable(GL_DEPTH_TEST); + mFuncs->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + mFuncs->glClearColor(0.0f, 0.0f, 0.0f, 1.0f); } /* override */ void DisplayGLWidget::paintGL() { - mFuncs->glDisable(GL_DEPTH_TEST); - mFuncs->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - mFuncs->glClearColor(0.0f, 0.0f, 0.0f, 1.0f); mFuncs->glEnable(GL_BLEND); if (maskTexture) { @@ -450,9 +453,25 @@ void DisplayGLWidget::paintGL() 0.0f, (float)mGuestResolution.height(), -1.0f, 1.0f); needScale = (mGuestResolution.width() != width()) - || (mGuestResolution.height() != height()); + || (mGuestResolution.height() != height()); + + // wait while "next" is being updated since it is fast enough. + textureListMutex.lock(); + if (next) { + if (current) { + qemu_mutex_lock(¤t->mutex); + current->available = true; + qemu_mutex_unlock(¤t->mutex); + } + current = next; + next = NULL; + } + textureListMutex.unlock(); + + if (current) { + drawQuad(current->tex, false); + } - drawQuad(dpyTexture, false); if (isTsEnabled) { drawMultiTouchPoints(); } diff --git a/tizen/src/ui/displayglwidget.h b/tizen/src/ui/displayglwidget.h index cc327f56a6..2008fc793e 100644 --- a/tizen/src/ui/displayglwidget.h +++ b/tizen/src/ui/displayglwidget.h @@ -34,9 +34,25 @@ #include "displaybase.h" +#include <QMutex> #include <QOpenGLWidget> #include <QMatrix4x4> +extern "C" { +#include "qemu/thread.h" + +// FIXME: move it to common header +struct dpy_item { + GLuint tex; + uint32_t width; + uint32_t height; + + bool available; + QemuMutex mutex; +}; +} + + class QOpenGLFunctions; class QOpenGLShaderProgram; class QOpenGLVertexArrayObject; @@ -53,7 +69,7 @@ public: QSize resolution, qreal scaleFactor); ~DisplayGLWidget(); - void changedTexture(unsigned int texture); + void changedTexture(struct dpy_item *tex); protected: void initializeGL(); @@ -82,7 +98,10 @@ private: QImage maskQImage; GLuint maskTexture; - GLuint dpyTexture; + dpy_item* current; + dpy_item* next; + QMutex textureListMutex; + GLuint mtTexture; QMatrix4x4 mOrtho; GLfloat mVertCoords[12]; @@ -92,6 +111,7 @@ private: QOpenGLBuffer *mVBO; QOpenGLShaderProgram *texProgram; QOpenGLShaderProgram *scaleProgram; + }; #endif // DISPLAYGLWIDGET_H diff --git a/tizen/src/ui/mainwindow.cpp b/tizen/src/ui/mainwindow.cpp index de3818d88d..52166086c3 100644 --- a/tizen/src/ui/mainwindow.cpp +++ b/tizen/src/ui/mainwindow.cpp @@ -533,9 +533,9 @@ void MainWindow::turnOffMovingMode() isMovingMode = false; } -void MainWindow::updateTexture(unsigned int texture) +void MainWindow::updateTexture(void *item) { - ((DisplayGLWidget *)getDisplay())->changedTexture(texture); + ((DisplayGLWidget *)getDisplay())->changedTexture((struct dpy_item *)item); } /* override */ diff --git a/tizen/src/ui/mainwindow.h b/tizen/src/ui/mainwindow.h index 55696070e2..84159c7cae 100644 --- a/tizen/src/ui/mainwindow.h +++ b/tizen/src/ui/mainwindow.h @@ -88,7 +88,7 @@ public: void turnOnMovingMode(); void turnOffMovingMode(); - void updateTexture(unsigned int texture); + void updateTexture(void *dpy_item); public slots: void slotContextMenu(const QPoint &pos); diff --git a/tizen/src/ui/qt5_supplement.cpp b/tizen/src/ui/qt5_supplement.cpp index 4ae6a2b43b..ba7091f89a 100644 --- a/tizen/src/ui/qt5_supplement.cpp +++ b/tizen/src/ui/qt5_supplement.cpp @@ -594,9 +594,9 @@ void qt5_process_captured(bool captured, void *pixels, int width, int height) } } -void qt5_update_texture(unsigned int tex_id) +void qt5_update_texture(void *dpy_item) { if (mainwindow) { - mainwindow->updateTexture(tex_id); + mainwindow->updateTexture(dpy_item); } } |