From 4b1a48f212c7624e9c1976c9e7c92a08b4fb307d Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Fri, 11 Sep 2009 16:37:53 +1000 Subject: Port the textures example to OpenGL/ES 2.0 Reviewed-by: trustme --- examples/opengl/opengl.pro | 6 +- examples/opengl/textures/glwidget.cpp | 110 ++++++++++++++++++++++++---------- examples/opengl/textures/glwidget.h | 10 +++- 3 files changed, 91 insertions(+), 35 deletions(-) diff --git a/examples/opengl/opengl.pro b/examples/opengl/opengl.pro index b86e0ba..2cb8227 100644 --- a/examples/opengl/opengl.pro +++ b/examples/opengl/opengl.pro @@ -5,9 +5,9 @@ contains(QT_CONFIG, opengles1)|contains(QT_CONFIG, opengles1cl)|contains(QT_CONF SUBDIRS = hellogl_es2 } else { SUBDIRS = hellogl_es - !contains(QT_CONFIG, opengles1cl) { - SUBDIRS += textures - } + } + !contains(QT_CONFIG, opengles1cl) { + SUBDIRS += textures } } else { SUBDIRS = 2dpainting \ diff --git a/examples/opengl/textures/glwidget.cpp b/examples/opengl/textures/glwidget.cpp index 024133b..6efd31a 100644 --- a/examples/opengl/textures/glwidget.cpp +++ b/examples/opengl/textures/glwidget.cpp @@ -44,16 +44,6 @@ #include "glwidget.h" -class CubeObject -{ -public: - GLuint textures[6]; - QVector vertices; - QVector texCoords; - - void draw(); -}; - GLWidget::GLWidget(QWidget *parent, QGLWidget *shareWidget) : QGLWidget(parent, shareWidget) { @@ -61,12 +51,13 @@ GLWidget::GLWidget(QWidget *parent, QGLWidget *shareWidget) xRot = 0; yRot = 0; zRot = 0; - cube = 0; +#ifdef QT_OPENGL_ES_2 + program = 0; +#endif } GLWidget::~GLWidget() { - delete cube; } QSize GLWidget::minimumSizeHint() const @@ -99,19 +90,90 @@ void GLWidget::initializeGL() glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); +#ifndef QT_OPENGL_ES_2 glEnable(GL_TEXTURE_2D); +#endif + +#ifdef QT_OPENGL_ES_2 + +#define PROGRAM_VERTEX_ATTRIBUTE 0 +#define PROGRAM_TEXCOORD_ATTRIBUTE 1 + + QGLShader *vshader = new QGLShader(QGLShader::VertexShader, this); + const char *vsrc = + "attribute highp vec4 vertex;\n" + "attribute mediump vec4 texCoord;\n" + "varying mediump vec4 texc;\n" + "uniform mediump mat4 matrix;\n" + "void main(void)\n" + "{\n" + " gl_Position = matrix * vertex;\n" + " texc = texCoord;\n" + "}\n"; + vshader->compile(vsrc); + + QGLShader *fshader = new QGLShader(QGLShader::FragmentShader, this); + const char *fsrc = + "uniform sampler2D texture;\n" + "varying mediump vec4 texc;\n" + "void main(void)\n" + "{\n" + " gl_FragColor = texture2D(texture, texc.st);\n" + "}\n"; + fshader->compile(fsrc); + + program = new QGLShaderProgram(this); + program->addShader(vshader); + program->addShader(fshader); + program->bindAttributeLocation("vertex", PROGRAM_VERTEX_ATTRIBUTE); + program->bindAttributeLocation("texCoord", PROGRAM_TEXCOORD_ATTRIBUTE); + program->link(); + + program->enable(); + program->setUniformValue("texture", 0); + +#endif } void GLWidget::paintGL() { qglClearColor(clearColor); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + +#if !defined(QT_OPENGL_ES_2) + glLoadIdentity(); glTranslatef(0.0f, 0.0f, -10.0f); glRotatef(xRot / 16.0f, 1.0f, 0.0f, 0.0f); glRotatef(yRot / 16.0f, 0.0f, 1.0f, 0.0f); glRotatef(zRot / 16.0f, 0.0f, 0.0f, 1.0f); - cube->draw(); + + glVertexPointer(3, GL_FLOAT, 0, vertices.constData()); + glTexCoordPointer(2, GL_FLOAT, 0, texCoords.constData()); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + +#else + + QMatrix4x4 m; + m.ortho(-0.5f, +0.5f, +0.5f, -0.5f, 4.0f, 15.0f); + m.translate(0.0f, 0.0f, -10.0f); + m.rotate(xRot / 16.0f, 1.0f, 0.0f, 0.0f); + m.rotate(yRot / 16.0f, 0.0f, 1.0f, 0.0f); + m.rotate(zRot / 16.0f, 0.0f, 0.0f, 1.0f); + + program->setUniformValue("matrix", m); + program->setAttributeArray + (PROGRAM_VERTEX_ATTRIBUTE, vertices.constData()); + program->setAttributeArray + (PROGRAM_TEXCOORD_ATTRIBUTE, texCoords.constData()); + +#endif + + for (int i = 0; i < 6; ++i) { + glBindTexture(GL_TEXTURE_2D, textures[i]); + glDrawArrays(GL_TRIANGLE_FAN, i * 4, 4); + } } void GLWidget::resizeGL(int width, int height) @@ -119,6 +181,7 @@ void GLWidget::resizeGL(int width, int height) int side = qMin(width, height); glViewport((width - side) / 2, (height - side) / 2, side, side); +#if !defined(QT_OPENGL_ES_2) glMatrixMode(GL_PROJECTION); glLoadIdentity(); #ifndef QT_OPENGL_ES @@ -127,6 +190,7 @@ void GLWidget::resizeGL(int width, int height) glOrthof(-0.5, +0.5, +0.5, -0.5, 4.0, 15.0); #endif glMatrixMode(GL_MODELVIEW); +#endif } void GLWidget::mousePressEvent(QMouseEvent *event) @@ -163,32 +227,18 @@ void GLWidget::makeObject() { { -1, -1, +1 }, { +1, -1, +1 }, { +1, +1, +1 }, { -1, +1, +1 } } }; - cube = new CubeObject(); - for (int j=0; j < 6; ++j) { - cube->textures[j] = bindTexture + textures[j] = bindTexture (QPixmap(QString(":/images/side%1.png").arg(j + 1)), GL_TEXTURE_2D); } for (int i = 0; i < 6; ++i) { for (int j = 0; j < 4; ++j) { - cube->texCoords.append + texCoords.append (QVector2D(j == 0 || j == 3, j == 0 || j == 1)); - cube->vertices.append + vertices.append (QVector3D(0.2 * coords[i][j][0], 0.2 * coords[i][j][1], 0.2 * coords[i][j][2])); } } } - -void CubeObject::draw() -{ - glVertexPointer(3, GL_FLOAT, 0, vertices.constData()); - glTexCoordPointer(2, GL_FLOAT, 0, texCoords.constData()); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - for (int i = 0; i < 6; ++i) { - glBindTexture(GL_TEXTURE_2D, textures[i]); - glDrawArrays(GL_TRIANGLE_FAN, i * 4, 4); - } -} diff --git a/examples/opengl/textures/glwidget.h b/examples/opengl/textures/glwidget.h index 46507ce..4dcff3b 100644 --- a/examples/opengl/textures/glwidget.h +++ b/examples/opengl/textures/glwidget.h @@ -42,9 +42,10 @@ #ifndef GLWIDGET_H #define GLWIDGET_H +#include #include -class CubeObject; +class QGLShaderProgram; class GLWidget : public QGLWidget { @@ -78,7 +79,12 @@ private: int xRot; int yRot; int zRot; - CubeObject *cube; + GLuint textures[6]; + QVector vertices; + QVector texCoords; +#ifdef QT_OPENGL_ES_2 + QGLShaderProgram *program; +#endif }; #endif -- cgit v0.12 From 02df785c9d95cdafe47a087d29a25f08bfb9e387 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Fri, 11 Sep 2009 16:50:24 +1000 Subject: Make mipmaps work on OpenGL/ES 2.0 Reviewed-by: Gunnar --- src/opengl/qgl.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 0e05b10..9148456 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -2070,6 +2070,9 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G glBindTexture(target, tx_id); glTexParameterf(target, GL_TEXTURE_MAG_FILTER, filtering); +#if defined(QT_OPENGL_ES_2) + bool genMipmap = false; +#endif if (glFormat.directRendering() && QGLExtensions::glExtensions & QGLExtensions::GenerateMipmap && target == GL_TEXTURE_2D @@ -2078,12 +2081,17 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G #ifdef QGL_BIND_TEXTURE_DEBUG printf(" - generating mipmaps\n"); #endif +#if !defined(QT_OPENGL_ES_2) glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST); #ifndef QT_OPENGL_ES glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); #else glTexParameterf(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); #endif +#else + glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST); + genMipmap = true; +#endif glTexParameterf(target, GL_TEXTURE_MIN_FILTER, options & QGLContext::LinearFilteringBindOption ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST); } else { @@ -2190,6 +2198,10 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G const QImage &constRef = img; // to avoid detach in bits()... glTexImage2D(target, 0, internalFormat, img.width(), img.height(), 0, externalFormat, pixel_type, constRef.bits()); +#if defined(QT_OPENGL_ES_2) + if (genMipmap) + glGenerateMipmap(target); +#endif #ifndef QT_NO_DEBUG GLenum error = glGetError(); if (error != GL_NO_ERROR) { -- cgit v0.12 From ebefcd1c0d4286a58bea2b4859d471df07f1f013 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 11 Sep 2009 10:00:26 +0300 Subject: Optimized S60 version check. Use pure Symbian code to get S60 version, because if done using QDir, there will be a call back to this method, resulting doing this expensive operation twice before the cache kicks in. Pure Symbian code also makes this method ~10x faster, speeding up the application launch. Task-number: 260757 Reviewed-by: Janne Anttila --- src/corelib/global/qglobal.cpp | 50 ++++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index a790dc1..9909b7b 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -75,6 +75,11 @@ #if defined(Q_OS_SYMBIAN) #include #include +#include +# include "private/qcore_symbian_p.h" + +_LIT(qt_S60Filter, "Series60v?.*.sis"); +_LIT(qt_S60SystemInstallDir, "z:\\system\\install\\"); #endif QT_BEGIN_NAMESPACE @@ -1786,28 +1791,31 @@ QSysInfo::S60Version QSysInfo::s60Version() if (cachedS60Version != -1) return cachedS60Version; - QDir dir(QLatin1String("z:\\system\\install")); - QStringList filters; - filters << QLatin1String("Series60v?.*.sis"); - dir.setNameFilters(filters); - - QStringList names = dir.entryList(QDir::NoFilter, QDir::Name | QDir::Reversed | QDir::IgnoreCase); - if (names.size() == 0) - return cachedS60Version = SV_S60_Unknown; - - int major, minor; - major = names[0][9].toAscii() - '0'; - minor = names[0][11].toAscii() - '0'; - if (major == 3) { - if (minor == 1) { - return cachedS60Version = SV_S60_3_1; - } else if (minor == 2) { - return cachedS60Version = SV_S60_3_2; - } - } else if (major == 5) { - if (minor == 0) { - return cachedS60Version = SV_S60_5_0; + // Use pure Symbian code, because if done using QDir, there will be a call back + // to this method, resulting doing this expensive operation twice before the cache kicks in. + // Pure Symbian code also makes this method ~10x faster, speeding up the application launch. + RFs rfs = qt_s60GetRFs(); + TFindFile fileFinder(rfs); + CDir* contents; + TInt err = fileFinder.FindWildByDir(qt_S60Filter, qt_S60SystemInstallDir, contents); + if (err == KErrNone) { + err = contents->Sort(EDescending|ESortByName); + if (err == KErrNone) { + TInt major = (*contents)[0].iName[9] - '0'; + TInt minor = (*contents)[0].iName[11] - '0'; + if (major == 3) { + if (minor == 1) { + return cachedS60Version = SV_S60_3_1; + } else if (minor == 2) { + return cachedS60Version = SV_S60_3_2; + } + } else if (major == 5) { + if (minor == 0) { + return cachedS60Version = SV_S60_5_0; + } + } } + delete contents; } return cachedS60Version = SV_S60_Unknown; -- cgit v0.12 From 22bbc21ba4c838d6afe000e07f70b470acc87d8b Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 10 Sep 2009 18:38:43 +0200 Subject: make tst_QLocalSocket::writeToClientAndDisconnect even more robust no more qApp->processEvents() ! Reviewed-by: ossi --- tests/auto/qlocalsocket/tst_qlocalsocket.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/qlocalsocket/tst_qlocalsocket.cpp b/tests/auto/qlocalsocket/tst_qlocalsocket.cpp index c0d870f..1180d4d 100644 --- a/tests/auto/qlocalsocket/tst_qlocalsocket.cpp +++ b/tests/auto/qlocalsocket/tst_qlocalsocket.cpp @@ -895,9 +895,9 @@ void tst_QLocalSocket::writeToClientAndDisconnect() QCOMPARE(clientSocket->write(buffer, sizeof(buffer)), (qint64)sizeof(buffer)); clientSocket->waitForBytesWritten(); clientSocket->disconnectFromServer(); - qApp->processEvents(); // give the socket the chance to receive data + QVERIFY(client.waitForReadyRead()); QCOMPARE(client.read(buffer, sizeof(buffer)), (qint64)sizeof(buffer)); - qApp->processEvents(); // give the socket the chance to close itself + QVERIFY(client.waitForDisconnected()); QCOMPARE(client.state(), QLocalSocket::UnconnectedState); } -- cgit v0.12 From 3fd024c6d9f0b0998efc44a783ee8390c6494dfa Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 10 Sep 2009 18:44:52 +0200 Subject: QLocalSocket (Win) emit readChannelFinished only once If pipeClosed is true, then we've already emitted the readChannelFinished signal. We must not do this in close() in that case. Reviewed-by: ossi --- src/network/socket/qlocalsocket_win.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp index d6e70be..8a745ab 100644 --- a/src/network/socket/qlocalsocket_win.cpp +++ b/src/network/socket/qlocalsocket_win.cpp @@ -375,7 +375,8 @@ void QLocalSocket::close() QIODevice::close(); d->state = ClosingState; emit stateChanged(d->state); - emit readChannelFinished(); + if (!d->pipeClosed) + emit readChannelFinished(); d->serverName = QString(); d->fullServerName = QString(); -- cgit v0.12 From fe9b8d7d2cf9c25ad8c594dda3339c32ea8e876b Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 11 Sep 2009 11:33:06 +0300 Subject: Changed Symbian tests to sleep only when run on emulator. Changed comment to be more accurate and changed ifdefs so that this will only be done for emulator. This issue needs more comprehensive analysis and wide test runs to determine what the pratical impact of removing this delay entirely would be. Task-number: 247270 Reviewed-by: Janne Anttila --- src/testlib/qtestcase.cpp | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 830a5ae..b7b2327 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -367,9 +367,9 @@ QT_BEGIN_NAMESPACE this macro. Unlike QBENCHMARK, the contents of the contained code block is only run - once. The elapsed time will be reported as "0" if it's to short to + once. The elapsed time will be reported as "0" if it's to short to be measured by the selected backend. (Use) - + \sa {QTestLib Manual#Creating a Benchmark}{Creating a Benchmark}, {Chapter 5: Writing a Benchmark}{Writing a Benchmark} */ @@ -738,7 +738,7 @@ QT_BEGIN_NAMESPACE \brief The QTouchEventSequence class is used to simulate a sequence of touch events. - To simulate a sequence of touch events on a specific device for a widget, call + To simulate a sequence of touch events on a specific device for a widget, call QTest::touchEvent to create a QTouchEventSequence instance. Add touch events to the sequence by calling press(), move(), release() and stationary(), and let the instance run out of scope to commit the sequence to the event system. @@ -756,7 +756,7 @@ QT_BEGIN_NAMESPACE Adds a press event for touchpoint \a touchId at position \a pt to this sequence and returns a reference to this QTouchEventSequence. - The position \a pt is interpreted as relative to \a widget. If \a widget is the null pointer, then + The position \a pt is interpreted as relative to \a widget. If \a widget is the null pointer, then \a pt is interpreted as relative to the widget provided when instantiating this QTouchEventSequence. Simulates that the user pressed the touch screen or pad with the finger identified by \a touchId. @@ -768,7 +768,7 @@ QT_BEGIN_NAMESPACE Adds a move event for touchpoint \a touchId at position \a pt to this sequence and returns a reference to this QTouchEventSequence. - The position \a pt is interpreted as relative to \a widget. If \a widget is the null pointer, then + The position \a pt is interpreted as relative to \a widget. If \a widget is the null pointer, then \a pt is interpreted as relative to the widget provided when instantiating this QTouchEventSequence. Simulates that the user moved the finger identified by \a touchId. @@ -779,8 +779,8 @@ QT_BEGIN_NAMESPACE Adds a release event for touchpoint \a touchId at position \a pt to this sequence and returns a reference to this QTouchEventSequence. - - The position \a pt is interpreted as relative to \a widget. If \a widget is the null pointer, then + + The position \a pt is interpreted as relative to \a widget. If \a widget is the null pointer, then \a pt is interpreted as relative to the widget provided when instantiating this QTouchEventSequence. Simulates that the user lifted the finger identified by \a touchId. @@ -791,7 +791,7 @@ QT_BEGIN_NAMESPACE Adds a stationary event for touchpoint \a touchId to this sequence and returns a reference to this QTouchEventSequence. - + Simulates that the user did not move the finger identified by \a touchId. */ @@ -1612,8 +1612,11 @@ int QTest::qExec(QObject *testObject, int argc, char **argv) } #endif -#ifdef Q_OS_SYMBIAN -//### FIX THIS temporary hack to delay execution of symbian os tests. Used to get emulator to stable state before running testcase +#if defined(Q_OS_SYMBIAN) && defined(Q_CC_NOKIAX86) + // Delay execution of tests in Symbian emulator. + // Needed to allow worst of other higher priority apps and services launched by emulator + // to get out of the way before we run our test. Otherwise some of the timing sensitive tests + // will not work properly. qSleep(3000); #endif @@ -2124,7 +2127,7 @@ bool QTest::compare_string_helper(const char *t1, const char *t2, const char *ac /*! \fn bool QTest::qCompare(bool const &t1, int const &t2, const char *actual, const char *expected, const char *file, int line) \internal */ - + /*! \fn bool QTest::qTest(const T& actual, const char *elementName, const char *actualStr, const char *expected, const char *file, int line) \internal */ -- cgit v0.12 From d753c7bc9028a97887d2c67f989d468cda39e1c6 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Fri, 11 Sep 2009 10:36:23 +0200 Subject: Fixed a bug in the autotest for q3progressbar. The "standard" test would sometimes fail (Mac OS X) because extra paint events could be generated, which would cause paintNumber to be > 1. Comparing it to 1 would fail. This test should be redesigned, I think. --- tests/auto/bic/tst_bic.cpp | 2 +- tests/auto/q3progressbar/tst_q3progressbar.cpp | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/tests/auto/bic/tst_bic.cpp b/tests/auto/bic/tst_bic.cpp index db0c5ba..82c8dc0 100644 --- a/tests/auto/bic/tst_bic.cpp +++ b/tests/auto/bic/tst_bic.cpp @@ -293,7 +293,7 @@ void tst_Bic::sizesAndVTables() bool isFailed = false; - qDebug() << oldLib.arg(libName); + //qDebug() << oldLib.arg(libName); if (oldLib.isEmpty() || !QFile::exists(oldLib.arg(libName))) QSKIP("No platform spec found for this platform/version.", SkipSingle); diff --git a/tests/auto/q3progressbar/tst_q3progressbar.cpp b/tests/auto/q3progressbar/tst_q3progressbar.cpp index c5485a7..34a95d3 100644 --- a/tests/auto/q3progressbar/tst_q3progressbar.cpp +++ b/tests/auto/q3progressbar/tst_q3progressbar.cpp @@ -93,11 +93,15 @@ class MyCustomProgressBar : public Q3ProgressBar void paintEvent(QPaintEvent * event) { paintNumber++; + qDebug() << "PAINT EVENT:" << paintNumber; Q3ProgressBar::paintEvent(event); } int paintNumber; }; +/* + Maybe this test should be redesigned. + */ void tst_Q3ProgressBar::setProgress() { MyCustomProgressBar * m_progressBar = new MyCustomProgressBar(); @@ -111,15 +115,21 @@ void tst_Q3ProgressBar::setProgress() m_progressBar->setProgress(m_progressBar->progress() + 1); QCOMPARE(oldValue + 1,m_progressBar->progress()); QApplication::processEvents(); - QVERIFY(m_progressBar->paintNumber >= 1); //it might be more than 1 because it is animated + // It might be > 1 because it is animated. + QVERIFY(m_progressBar->paintNumber >= 1); + qDebug() << "Animation test: paintNumber =" << m_progressBar->paintNumber; + //standard case m_progressBar->setTotalSteps(3); m_progressBar->setProgress(0); m_progressBar->paintNumber = 0; m_progressBar->setProgress(m_progressBar->progress() + 1); QApplication::processEvents(); - QCOMPARE(m_progressBar->paintNumber,1); + + // It might be > 1 because other events might cause painting. + QVERIFY(m_progressBar->paintNumber >= 1); + qDebug() << "Standard test: paintNumber =" << m_progressBar->paintNumber; } QTEST_MAIN(tst_Q3ProgressBar) -- cgit v0.12