From 7a54885b1df9baf793374e3cb9fdf8be93ee7c80 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Tue, 4 Jan 2011 15:35:58 +0100 Subject: Fix regression in text rendering in OpenGL2 engine Change 532115bcaa370af827a5cbad017b272842c5aacf introduced a regression by fixing a typo in the QT_OPENGL_ES_2 macro. This caused a broken and untested code path to be used in the GLES2 case. Since the QImage scanlines are 32 bit aligned, QImage::width() cannot be used when copying the data. Rather than pass in bytesPerLine() to the GL function, I opted to revert to the proven behavior, where the pad bytes are never read by GL but each scanline is copied separately, to avoid further regressions on different hardware. This also seems like the more correct approach, as the pad bytes should ideally not be copied into the cache texture. Reviewed-by: Samuel --- src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp index 1b879c3..ad1bf31 100644 --- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp +++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp @@ -293,9 +293,6 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph) if (mask.format() == QImage::Format_RGB32) { glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_BGRA, GL_UNSIGNED_BYTE, mask.bits()); } else { -#ifdef QT_OPENGL_ES_2 - glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_ALPHA, GL_UNSIGNED_BYTE, mask.bits()); -#else // glTexSubImage2D() might cause some garbage to appear in the texture if the mask width is // not a multiple of four bytes. The bug appeared on a computer with 32-bit Windows Vista // and nVidia GeForce 8500GT. GL_UNPACK_ALIGNMENT is set to four bytes, 'mask' has a @@ -307,7 +304,6 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph) for (int i = 0; i < maskHeight; ++i) glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y + i, maskWidth, 1, GL_ALPHA, GL_UNSIGNED_BYTE, mask.scanLine(i)); -#endif } } -- cgit v0.12 From 64852122ba71bbb297b4f1e440f6fabee16ca2fe Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Fri, 7 Jan 2011 16:15:25 +0100 Subject: Fix crash in QTextBlock::next()/previous() We should check not just p but also n in next()/previous(), which is what isValid() does. Otherwise n == 0 will cause crash in QFragmentMap. Task-number: QTBUG-16279 Reviewed-by: Eskil --- src/gui/text/qtextobject.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/text/qtextobject.cpp b/src/gui/text/qtextobject.cpp index ea2ef2d..4b92379 100644 --- a/src/gui/text/qtextobject.cpp +++ b/src/gui/text/qtextobject.cpp @@ -1488,7 +1488,7 @@ QTextBlock::iterator QTextBlock::end() const */ QTextBlock QTextBlock::next() const { - if (!p) + if (!isValid()) return QTextBlock(); return QTextBlock(p, p->blockMap().next(n)); @@ -1504,7 +1504,7 @@ QTextBlock QTextBlock::next() const */ QTextBlock QTextBlock::previous() const { - if (!p) + if (!isValid()) return QTextBlock(); return QTextBlock(p, p->blockMap().previous(n)); -- cgit v0.12 From 2b1b617664bfc78f6e95e53dc0f9749bd1f2d27a Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Fri, 7 Jan 2011 15:57:28 +0000 Subject: Fix handle leak in symbian QTimer implementation The timer handle was only being closed when a timer was cancelled, which resulted in a leak for one shot timers that have completed normally. Instead the timer is now closed in a destructor (closing null handles is safe, so it doesn't matter if the handle was never created - e.g. in the case of a zero timer) Also added a handle check before creating a timer to prevent a leak in case the start function is called twice in the backend. Task-number: QTBUG-16380 Reviewed-by: mread --- src/corelib/kernel/qeventdispatcher_symbian.cpp | 6 ++-- tests/auto/qtimer/tst_qtimer.cpp | 38 +++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/corelib/kernel/qeventdispatcher_symbian.cpp b/src/corelib/kernel/qeventdispatcher_symbian.cpp index bb9bd01..99c4087 100644 --- a/src/corelib/kernel/qeventdispatcher_symbian.cpp +++ b/src/corelib/kernel/qeventdispatcher_symbian.cpp @@ -217,13 +217,13 @@ QTimerActiveObject::QTimerActiveObject(QEventDispatcherSymbian *dispatcher, Symb QTimerActiveObject::~QTimerActiveObject() { Cancel(); + m_rTimer.Close(); //close of null handle is safe } void QTimerActiveObject::DoCancel() { if (m_timerInfo->interval > 0) { m_rTimer.Cancel(); - m_rTimer.Close(); } else { if (iStatus.Int() == KRequestPending) { TRequestStatus *status = &iStatus; @@ -302,7 +302,9 @@ void QTimerActiveObject::Start() CActiveScheduler::Add(this); m_timerInfo->msLeft = m_timerInfo->interval; if (m_timerInfo->interval > 0) { - m_rTimer.CreateLocal(); + if (!m_rTimer.Handle()) { + qt_symbian_throwIfError(m_rTimer.CreateLocal()); + } StartTimer(); } else { iStatus = KRequestPending; diff --git a/tests/auto/qtimer/tst_qtimer.cpp b/tests/auto/qtimer/tst_qtimer.cpp index 102308e..e964728 100644 --- a/tests/auto/qtimer/tst_qtimer.cpp +++ b/tests/auto/qtimer/tst_qtimer.cpp @@ -90,6 +90,9 @@ private slots: void QTBUG13633_dontBlockEvents(); void postedEventsShouldNotStarveTimers(); +#ifdef Q_OS_SYMBIAN + void handleLeaks(); +#endif }; class TimerHelper : public QObject @@ -750,5 +753,40 @@ void tst_QTimer::postedEventsShouldNotStarveTimers() QVERIFY(timerHelper.count > 5); } +#ifdef Q_OS_SYMBIAN +void tst_QTimer::handleLeaks() +{ + const int timercount = 5; + int processhandles_start; + int threadhandles_start; + RThread().HandleCount(processhandles_start, threadhandles_start); + { + TimerHelper timerHelper; + QList timers; + for (int i=0;isetSingleShot(true); + timer->start(i); //test both zero and normal timeouts + } + int processhandles_mid; + int threadhandles_mid; + RThread().HandleCount(processhandles_mid, threadhandles_mid); + qDebug() << threadhandles_mid - threadhandles_start << "new thread owned handles"; + QTest::qWait(100); + QCOMPARE(timerHelper.count, timercount); + qDeleteAll(timers); + } + int processhandles_end; + int threadhandles_end; + RThread().HandleCount(processhandles_end, threadhandles_end); + QCOMPARE(threadhandles_end, threadhandles_start); //RTimer::CreateLocal creates a thread owned handle + //Can not verify process handles because QObject::connect may create up to 2 mutexes + //from a QMutexPool (4 process owned handles with open C imp.) + //QCOMPARE(processhandles_end, processhandles_start); +} +#endif + QTEST_MAIN(tst_QTimer) #include "tst_qtimer.moc" -- cgit v0.12 From d62e9f4a6fe199ae790b1561fd4ba9ea84bd4d1e Mon Sep 17 00:00:00 2001 From: Jani Hautakangas Date: Mon, 10 Jan 2011 13:22:15 +0200 Subject: Setting WA_TranslucentBackground after winid() is ineffective on Symbian. Currently Symbian doesn't support semi-transparent EGL surfaces. WA_TranslucentBackground attribute is ineffective if set after EGL surface creation. To enable translucency in this case we need to recreate backing store to get raster surface which supports translucency. Task-number: QT-4416 Reviewed-by: Jason Barron --- src/gui/kernel/qwidget_s60.cpp | 8 ++++++++ src/gui/painting/qgraphicssystem_runtime.cpp | 3 ++- src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp | 2 ++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index d6ad3c3..d55c21e 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -780,6 +780,14 @@ void QWidgetPrivate::s60UpdateIsOpaque() if (window->SetTransparencyAlphaChannel() == KErrNone) { window->SetBackgroundColor(TRgb(255, 255, 255, 0)); extra->topextra->nativeWindowTransparencyEnabled = 1; + + if (extra->topextra->backingStore.data() && + QApplicationPrivate::graphics_system_name == QLatin1String("openvg")) { + // Semi-transparent EGL surfaces aren't supported. We need to + // recreate backing store to get translucent surface (raster surface). + extra->topextra->backingStore.create(q); + extra->topextra->backingStore.registerWidget(q); + } } } else if (extra->topextra->nativeWindowTransparencyEnabled) { window->SetTransparentRegion(TRegionFix<1>()); diff --git a/src/gui/painting/qgraphicssystem_runtime.cpp b/src/gui/painting/qgraphicssystem_runtime.cpp index a9fbbee..db3b0d8 100644 --- a/src/gui/painting/qgraphicssystem_runtime.cpp +++ b/src/gui/painting/qgraphicssystem_runtime.cpp @@ -322,7 +322,6 @@ QRuntimeGraphicsSystem::QRuntimeGraphicsSystem() : m_windowSurfaceDestroyPolicy(DestroyImmediately), m_graphicsSystem(0) { - QApplicationPrivate::graphics_system_name = QLatin1String("runtime"); QApplicationPrivate::runtime_graphics_system = true; #ifdef QT_DEFAULT_RUNTIME_SYSTEM @@ -336,6 +335,8 @@ QRuntimeGraphicsSystem::QRuntimeGraphicsSystem() #endif m_graphicsSystem = QGraphicsSystemFactory::create(m_graphicsSystemName); + + QApplicationPrivate::graphics_system_name = QLatin1String("runtime"); } diff --git a/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp b/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp index 9674233..5f4941f 100644 --- a/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp +++ b/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp @@ -45,11 +45,13 @@ #if defined(Q_OS_SYMBIAN) && !defined(Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE) #include #endif +#include QT_BEGIN_NAMESPACE QVGGraphicsSystem::QVGGraphicsSystem() { + QApplicationPrivate::graphics_system_name = QLatin1String("openvg"); } QPixmapData *QVGGraphicsSystem::createPixmapData(QPixmapData::PixelType type) const -- cgit v0.12