From 4a1ae3d1b4e8e032b1c978fcc7e1812e37e1f047 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 27 Apr 2011 15:18:58 +0200 Subject: Make translucent windows working properly with OpenVG. The OpenVG engine correctly uses vgClear() to fill the surface with transparent pixels whenever the window has the WA_TranslucentBackground attribute enabled. However both scissoring and masking affects the operation of vgClear(). Drawing artifacts were previously visible due this, simply because scissoring was left enabled by the VG paint engine, and the filling with transparent pixels happens in the window surface's beginPaint() that is called between the paint engine's end() (for the previous paint) and begin() (for the next paint). Task-number: QT-4907 Reviewed-by: Jani Hautakangas --- src/openvg/qpaintengine_vg.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp index ebdfa5f..648415c 100644 --- a/src/openvg/qpaintengine_vg.cpp +++ b/src/openvg/qpaintengine_vg.cpp @@ -1533,6 +1533,8 @@ bool QVGPaintEngine::begin(QPaintDevice *pdev) bool QVGPaintEngine::end() { + vgSeti(VG_SCISSORING, VG_FALSE); + vgSeti(VG_MASKING, VG_FALSE); return true; } @@ -3759,6 +3761,8 @@ void QVGPaintEngine::beginNativePainting() #if !defined(QVG_NO_DRAW_GLYPHS) d->setTransform(VG_MATRIX_GLYPH_USER_TO_SURFACE, d->pathTransform); #endif + vgSeti(VG_SCISSORING, VG_FALSE); + vgSeti(VG_MASKING, VG_FALSE); d->rawVG = true; } @@ -3819,6 +3823,7 @@ void QVGPaintEngine::restoreState(QPaintEngine::DirtyFlags dirty) if ((dirty & QPaintEngine::DirtyBrushOrigin) != 0) brushOriginChanged(); d->fillRule = 0; + d->clearColor = QColor(); if ((dirty & QPaintEngine::DirtyOpacity) != 0) opacityChanged(); if ((dirty & QPaintEngine::DirtyTransform) != 0) -- cgit v0.12 From d45ec470519d1075ebf299b74cbb846a0c7d99af Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 27 Apr 2011 15:02:32 +0200 Subject: Upload VGImage data when drawing pixmaps that are being painted into. When a painter is open on a pixmap's underlying QVolatileImage, it is better to upload the VGImage content every time the pixmap is drawn on the screen, in order to enable showing animations that are created by continously rendering into the same pixmap and keeping the same painter open. Task-number: QT-4002 Reviewed-by: Jason Barron --- src/gui/image/qvolatileimage.cpp | 5 +++++ src/gui/image/qvolatileimage_p.h | 1 + src/openvg/qpixmapdata_vg.cpp | 2 +- src/s60installs/bwins/QtGuiu.def | 1 + src/s60installs/eabi/QtGuiu.def | 1 + tests/auto/qpixmap/tst_qpixmap.cpp | 46 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 55 insertions(+), 1 deletion(-) diff --git a/src/gui/image/qvolatileimage.cpp b/src/gui/image/qvolatileimage.cpp index 098e9a1..f5076e1 100644 --- a/src/gui/image/qvolatileimage.cpp +++ b/src/gui/image/qvolatileimage.cpp @@ -103,6 +103,11 @@ QVolatileImage &QVolatileImage::operator=(const QVolatileImage &rhs) return *this; } +bool QVolatileImage::paintingActive() const +{ + return d->pengine && d->pengine->isActive(); +} + bool QVolatileImage::isNull() const { return d->image.isNull(); diff --git a/src/gui/image/qvolatileimage_p.h b/src/gui/image/qvolatileimage_p.h index fc5d6b1..d835f45 100644 --- a/src/gui/image/qvolatileimage_p.h +++ b/src/gui/image/qvolatileimage_p.h @@ -71,6 +71,7 @@ public: ~QVolatileImage(); QVolatileImage &operator=(const QVolatileImage &rhs); + bool paintingActive() const; bool isNull() const; QImage::Format format() const; int width() const; diff --git a/src/openvg/qpixmapdata_vg.cpp b/src/openvg/qpixmapdata_vg.cpp index 80f5b2f..eae10c8 100644 --- a/src/openvg/qpixmapdata_vg.cpp +++ b/src/openvg/qpixmapdata_vg.cpp @@ -377,7 +377,7 @@ VGImage QVGPixmapData::toVGImage() QVGImagePool::instance()->useImage(this); } - if (!source.isNull() && recreate) { + if (!source.isNull() && (recreate || source.paintingActive())) { source.beginDataAccess(); vgImageSubData (vgImage, diff --git a/src/s60installs/bwins/QtGuiu.def b/src/s60installs/bwins/QtGuiu.def index 26a0761..45a8d7b 100644 --- a/src/s60installs/bwins/QtGuiu.def +++ b/src/s60installs/bwins/QtGuiu.def @@ -12981,4 +12981,5 @@ EXPORTS ?depth@QVolatileImage@@QBEHXZ @ 12980 NONAME ; int QVolatileImage::depth(void) const ?releaseCachedResources@QGraphicsSystem@@UAEXXZ @ 12981 NONAME ; void QGraphicsSystem::releaseCachedResources(void) ?qt_s60_setPartialScreenInputMode@@YAX_N@Z @ 12982 NONAME ; void qt_s60_setPartialScreenInputMode(bool) + ?paintingActive@QVolatileImage@@QBE_NXZ @ 12983 NONAME ; bool QVolatileImage::paintingActive(void) const diff --git a/src/s60installs/eabi/QtGuiu.def b/src/s60installs/eabi/QtGuiu.def index b6a24ab..82ded24 100644 --- a/src/s60installs/eabi/QtGuiu.def +++ b/src/s60installs/eabi/QtGuiu.def @@ -12182,4 +12182,5 @@ EXPORTS _ZNK14QVolatileImage9constBitsEv @ 12181 NONAME _ZN15QGraphicsSystem22releaseCachedResourcesEv @ 12182 NONAME _Z32qt_s60_setPartialScreenInputModeb @ 12183 NONAME + _ZNK14QVolatileImage14paintingActiveEv @ 12184 NONAME diff --git a/tests/auto/qpixmap/tst_qpixmap.cpp b/tests/auto/qpixmap/tst_qpixmap.cpp index 0b5c30b..d103cb7 100644 --- a/tests/auto/qpixmap/tst_qpixmap.cpp +++ b/tests/auto/qpixmap/tst_qpixmap.cpp @@ -194,6 +194,8 @@ private slots: #if defined(Q_OS_SYMBIAN) && !defined(QT_NO_OPENVG) void vgImageReadBack(); #endif + + void drawPixmapWhilePainterOpen(); }; static bool lenientCompare(const QPixmap &actual, const QPixmap &expected) @@ -1881,5 +1883,49 @@ void tst_QPixmap::vgImageReadBack() } #endif // Symbian & OpenVG +class PixmapWidget : public QWidget +{ +public: + PixmapWidget(QPixmap &pixmap) : QWidget(0), m_pixmap(pixmap) + { + resize(pixmap.width(), pixmap.height()); + } + +protected: + void paintEvent(QPaintEvent *) + { + QPainter p(this); + p.drawPixmap(0, 0, m_pixmap); + } + +private: + QPixmap &m_pixmap; +}; + +void tst_QPixmap::drawPixmapWhilePainterOpen() +{ + int size = 100; + QPixmap pix(size, size); + pix.fill(Qt::red); + + PixmapWidget w(pix); + w.show(); + QTest::qWaitForWindowShown(&w); + QTest::qWait(1000); + + QPainter p(&pix); + p.fillRect(0, 0, size, size, Qt::blue); + w.update(); + QTest::qWait(1000); + + p.fillRect(0, 0, size, size, Qt::green); + w.update(); + QTest::qWait(1000); + + QPixmap actual = QPixmap::grabWindow(w.effectiveWinId(), 0, 0, size, size); + + QVERIFY(lenientCompare(actual, pix)); +} + QTEST_MAIN(tst_QPixmap) #include "tst_qpixmap.moc" -- cgit v0.12 From a690e560b38385ebb9cd83288e8660d2a4ca2fde Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 28 Apr 2011 14:07:47 +0200 Subject: Made the autotest for drawing pixmaps with painter open more fail safe. The autotest relies on QPixmap::grabWindow() which causes random CI failures because it may capture bogus content if some other window comes to foreground, focus is changed, etc. To overcome these false positives the pixmap content comparison is now only done when the captured content is one of the three possible images. If it is anything else, we cannot verify so the case is skipped. Task-number: QT-4002 Reviewed-by: TRUSTME --- tests/auto/qpixmap/tst_qpixmap.cpp | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/tests/auto/qpixmap/tst_qpixmap.cpp b/tests/auto/qpixmap/tst_qpixmap.cpp index d103cb7..0b2f527 100644 --- a/tests/auto/qpixmap/tst_qpixmap.cpp +++ b/tests/auto/qpixmap/tst_qpixmap.cpp @@ -1904,27 +1904,42 @@ private: void tst_QPixmap::drawPixmapWhilePainterOpen() { - int size = 100; + const int delay = 1000; + const int size = 100; + const QColor colors[] = { Qt::red, Qt::blue, Qt::green }; + QPixmap pix(size, size); - pix.fill(Qt::red); + pix.fill(colors[0]); PixmapWidget w(pix); w.show(); QTest::qWaitForWindowShown(&w); - QTest::qWait(1000); + QTest::qWait(delay); QPainter p(&pix); - p.fillRect(0, 0, size, size, Qt::blue); + p.fillRect(0, 0, size, size, colors[1]); w.update(); - QTest::qWait(1000); + QTest::qWait(delay); - p.fillRect(0, 0, size, size, Qt::green); + p.fillRect(0, 0, size, size, colors[2]); w.update(); - QTest::qWait(1000); + QTest::qWait(delay); QPixmap actual = QPixmap::grabWindow(w.effectiveWinId(), 0, 0, size, size); - QVERIFY(lenientCompare(actual, pix)); + // If we captured some bogus content with grabWindow(), the comparison makes no sense + // because it cannot prove the feature is broken. + QPixmap guard(size, size); + bool matchesColors = false; + for (size_t i = 0; i < sizeof(colors) / sizeof(const QColor); ++i) { + guard.fill(colors[i]); + matchesColors |= lenientCompare(actual, guard); + } + if (!matchesColors) { + QSKIP("Skipping verification due to grabWindow() issue", SkipSingle); + } else { + QVERIFY(lenientCompare(actual, pix)); + } } QTEST_MAIN(tst_QPixmap) -- cgit v0.12