summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern Erik Nilsen <bjorn.nilsen@nokia.com>2009-04-27 17:16:59 +0200
committerBjoern Erik Nilsen <bjorn.nilsen@nokia.com>2009-04-27 17:35:46 +0200
commit8ebe882b077fffedc3ff80fb80d2e181d5e56ab8 (patch)
tree4d545f2c36bfb803fefc7bc66cbc983e4565d578
parent73fefcfb67b2de42a0675eb88aaa5cb2751402e6 (diff)
Fixes wrong QPaintEvent::region() in QGLWidget::paintEvent.
QGLWidget does not support partial updates unless the context is single buffered and auto-fill background is disabled. The problem was that QPaintEvent::region() returned the requested update region without taking into account the limitation of QGLWidget. If QGLWidget doesn't support partial updates, it means everything has to be updated, and QPaintEvent::region() must return the whole widget rect. Auto test included. Task-number: 241785 Reviewed-by: Trond
-rw-r--r--src/gui/kernel/qwidget.cpp1
-rw-r--r--src/gui/kernel/qwidget_p.h1
-rw-r--r--src/gui/painting/qbackingstore.cpp11
-rw-r--r--src/opengl/qgl.cpp4
-rw-r--r--tests/auto/qgl/tst_qgl.cpp61
5 files changed, 76 insertions, 2 deletions
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index eb2e9f78a6..f61260148b 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -183,6 +183,7 @@ QWidgetPrivate::QWidgetPrivate(int version) :
,inDirtyList(0)
,isScrolled(0)
,isMoved(0)
+ ,usesDoubleBufferedGLContext(0)
#ifdef Q_WS_WIN
,noPaintOnScreen(0)
#endif
diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h
index 423e833948..db78682647 100644
--- a/src/gui/kernel/qwidget_p.h
+++ b/src/gui/kernel/qwidget_p.h
@@ -536,6 +536,7 @@ public:
uint inDirtyList : 1;
uint isScrolled : 1;
uint isMoved : 1;
+ uint usesDoubleBufferedGLContext : 1;
#ifdef Q_WS_WIN
uint noPaintOnScreen : 1; // see qwidget_win.cpp ::paintEngine()
diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp
index fbac811a0b..34df6c96c8 100644
--- a/src/gui/painting/qbackingstore.cpp
+++ b/src/gui/painting/qbackingstore.cpp
@@ -1517,13 +1517,20 @@ void QWidgetPrivate::repaint_sys(const QRegion &rgn)
extra->staticContentsSize = data.crect.size();
}
+ QPaintEngine *engine = q->paintEngine();
+ // QGLWidget does not support partial updates if:
+ // 1) The context is double buffered
+ // 2) The context is single buffered and auto-fill background is enabled.
+ const bool noPartialUpdateSupport = (engine && engine->type() == QPaintEngine::OpenGL)
+ && (usesDoubleBufferedGLContext || q->autoFillBackground());
+ QRegion toBePainted(noPartialUpdateSupport ? q->rect() : rgn);
+
#ifdef Q_WS_MAC
// No difference between update() and repaint() on the Mac.
- update_sys(rgn);
+ update_sys(toBePainted);
return;
#endif
- QRegion toBePainted(rgn);
toBePainted &= clipRect();
clipToEffectiveMask(toBePainted);
if (toBePainted.isEmpty())
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index b4a0e5c909..8ffee87889 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -2398,6 +2398,10 @@ bool QGLContext::create(const QGLContext* shareContext)
return false;
reset();
d->valid = chooseContext(shareContext);
+ if (d->valid && d->paintDevice->devType() == QInternal::Widget) {
+ QWidgetPrivate *wd = qt_widget_private(static_cast<QWidget *>(d->paintDevice));
+ wd->usesDoubleBufferedGLContext = d->glFormat.doubleBuffer();
+ }
if (d->sharing) // ok, we managed to share
qgl_share_reg()->addShare(this, shareContext);
return d->valid;
diff --git a/tests/auto/qgl/tst_qgl.cpp b/tests/auto/qgl/tst_qgl.cpp
index a64dfc4bad..f982e6db2c 100644
--- a/tests/auto/qgl/tst_qgl.cpp
+++ b/tests/auto/qgl/tst_qgl.cpp
@@ -66,6 +66,8 @@ private slots:
void getSetCheck();
void openGLVersionCheck();
void graphicsViewClipping();
+ void partialGLWidgetUpdates_data();
+ void partialGLWidgetUpdates();
};
tst_QGL::tst_QGL()
@@ -404,5 +406,64 @@ void tst_QGL::graphicsViewClipping()
#endif
}
+void tst_QGL::partialGLWidgetUpdates_data()
+{
+ QTest::addColumn<bool>("doubleBufferedContext");
+ QTest::addColumn<bool>("autoFillBackground");
+ QTest::addColumn<bool>("supportsPartialUpdates");
+
+ QTest::newRow("Double buffered context") << true << true << false;
+ QTest::newRow("Double buffered context without auto-fill background") << true << false << false;
+ QTest::newRow("Single buffered context") << false << true << false;
+ QTest::newRow("Single buffered context without auto-fill background") << false << false << true;
+}
+
+void tst_QGL::partialGLWidgetUpdates()
+{
+#ifdef QT_NO_OPENGL
+ QSKIP("QGL not yet supported", SkipAll);
+#else
+ if (!QGLFormat::hasOpenGL())
+ QSKIP("QGL not supported on this platform", SkipAll);
+
+ QFETCH(bool, doubleBufferedContext);
+ QFETCH(bool, autoFillBackground);
+ QFETCH(bool, supportsPartialUpdates);
+
+ class MyGLWidget : public QGLWidget
+ {
+ public:
+ QRegion paintEventRegion;
+ void paintEvent(QPaintEvent *e)
+ {
+ paintEventRegion = e->region();
+ }
+ };
+
+ QGLFormat format = QGLFormat::defaultFormat();
+ format.setDoubleBuffer(doubleBufferedContext);
+ QGLFormat::setDefaultFormat(format);
+
+ MyGLWidget widget;
+ widget.setFixedSize(150, 150);
+ widget.setAutoFillBackground(autoFillBackground);
+ widget.show();
+#ifdef Q_WS_X11
+ qt_x11_wait_for_window_manager(&widget);
+#endif
+ QTest::qWait(200);
+
+ if (widget.format().doubleBuffer() != doubleBufferedContext)
+ QSKIP("Platform does not support requested format", SkipAll);
+
+ widget.paintEventRegion = QRegion();
+ widget.repaint(50, 50, 50, 50);
+ if (supportsPartialUpdates)
+ QCOMPARE(widget.paintEventRegion, QRegion(50, 50, 50, 50));
+ else
+ QCOMPARE(widget.paintEventRegion, QRegion(widget.rect()));
+#endif
+}
+
QTEST_MAIN(tst_QGL)
#include "tst_qgl.moc"