summaryrefslogtreecommitdiffstats
path: root/tests/auto/gui/qopengl
diff options
context:
space:
mode:
authorJulian Thijssen <Nimthora@gmail.com>2016-07-27 15:45:31 +0200
committerLaszlo Agocs <laszlo.agocs@qt.io>2017-01-23 11:34:05 +0000
commit7dc88b68904c7f1b7e012bd65ccdcbf48cc6e2e0 (patch)
tree6de47b86b99200b999eddd8de0f07c2e86d8e027 /tests/auto/gui/qopengl
parentda4b6c4774c0adf8dee5ee4a9a8d9d24967ede3c (diff)
Add support for OpenGL 3.2+ core profile contexts in QPainter
This change allows painting via QPainter onto a QOpenGLWindow, QOpenGLWidget or QOpenGLFramebufferObject when an core profile context is in use. This is important on macOS in particular, where compatibility profiles are not available, and so the only way to use modern OpenGL is via a core profile context. Added core profile compatible shaders with moder GLSL keywords. The paint engine binds a VAO and two VBOs from now on, whenever VAOs are supported. Note that this changes behavior also for OpenGL 2.x context that have VAO support via extensions. The Lancelot test suite gains support for core profile contexts. This can be triggered via -coreglbuffer in place of -glbuffer when manually inspecting via 'lance', while tst_lancelot will automatically run core context-based tests whenever supported. Task-number: QTBUG-33535 Change-Id: I6323a7ea2aaa9e111651ebbffd3e40259c8e7a9c Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'tests/auto/gui/qopengl')
-rw-r--r--tests/auto/gui/qopengl/tst_qopengl.cpp72
1 files changed, 64 insertions, 8 deletions
diff --git a/tests/auto/gui/qopengl/tst_qopengl.cpp b/tests/auto/gui/qopengl/tst_qopengl.cpp
index 44921f68aa..7451ef92ee 100644
--- a/tests/auto/gui/qopengl/tst_qopengl.cpp
+++ b/tests/auto/gui/qopengl/tst_qopengl.cpp
@@ -86,6 +86,7 @@ private slots:
void fboMRT_differentFormats();
void openGLPaintDevice_data();
void openGLPaintDevice();
+ void openGLPaintDeviceWithChangingContext();
void aboutToBeDestroyed();
void sizeLessWindow();
void QTBUG15621_triangulatingStrokerDivZero();
@@ -948,6 +949,14 @@ void tst_QOpenGL::openGLPaintDevice_data()
QTest::newRow("Using QOffscreenSurface - RGB16") << int(QSurface::Offscreen) << QImage::Format_RGB16;
}
+static void drawColoredRects(QPainter *p, const QSize &size)
+{
+ p->fillRect(0, 0, size.width() / 2, size.height() / 2, Qt::red);
+ p->fillRect(size.width() / 2, 0, size.width() / 2, size.height() / 2, Qt::green);
+ p->fillRect(size.width() / 2, size.height() / 2, size.width() / 2, size.height() / 2, Qt::blue);
+ p->fillRect(0, size.height() / 2, size.width() / 2, size.height() / 2, Qt::white);
+}
+
void tst_QOpenGL::openGLPaintDevice()
{
#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(__x86_64__)
@@ -970,10 +979,7 @@ void tst_QOpenGL::openGLPaintDevice()
QImage image(size, imageFormat);
QPainter p(&image);
- p.fillRect(0, 0, image.width() / 2, image.height() / 2, Qt::red);
- p.fillRect(image.width() / 2, 0, image.width() / 2, image.height() / 2, Qt::green);
- p.fillRect(image.width() / 2, image.height() / 2, image.width() / 2, image.height() / 2, Qt::blue);
- p.fillRect(0, image.height() / 2, image.width() / 2, image.height() / 2, Qt::white);
+ drawColoredRects(&p, image.size());
p.end();
QOpenGLFramebufferObject fbo(size);
@@ -981,10 +987,7 @@ void tst_QOpenGL::openGLPaintDevice()
QOpenGLPaintDevice device(size);
QVERIFY(p.begin(&device));
- p.fillRect(0, 0, image.width() / 2, image.height() / 2, Qt::red);
- p.fillRect(image.width() / 2, 0, image.width() / 2, image.height() / 2, Qt::green);
- p.fillRect(image.width() / 2, image.height() / 2, image.width() / 2, image.height() / 2, Qt::blue);
- p.fillRect(0, image.height() / 2, image.width() / 2, image.height() / 2, Qt::white);
+ drawColoredRects(&p, image.size());
p.end();
QImage actual = fbo.toImage().convertToFormat(imageFormat);
@@ -1010,6 +1013,59 @@ void tst_QOpenGL::openGLPaintDevice()
QCOMPARE(image, actual);
}
+void tst_QOpenGL::openGLPaintDeviceWithChangingContext()
+{
+ QScopedPointer<QSurface> surface(createSurface(QSurface::Window));
+ const QSize size(512, 512);
+
+ // QOpenGLPaintDevice has a thread-local paint engine. Therefore render
+ // twice, with a different context and device. Under the hood it will
+ // still use the same paint engine!
+
+ QOpenGLContext ctx;
+ QVERIFY(ctx.create());
+ QVERIFY(ctx.makeCurrent(surface.data()));
+
+ QOpenGLFramebufferObject fbo(size);
+ QVERIFY(fbo.bind());
+
+ QOpenGLPaintDevice device(size);
+
+ QPainter p;
+ QVERIFY(p.begin(&device));
+ drawColoredRects(&p, size);
+ p.end();
+
+ QImage img1 = fbo.toImage();
+
+ QOpenGLContext ctx2;
+ // When supported, test the special case, where the second context is
+ // totally incompatible due to being a core profile one.
+ QSurfaceFormat coreFormat;
+ coreFormat.setVersion(3, 2);
+ coreFormat.setProfile(QSurfaceFormat::CoreProfile);
+ ctx2.setFormat(coreFormat);
+ if (!ctx2.create() || !ctx2.makeCurrent(surface.data())) {
+ ctx2.setFormat(QSurfaceFormat());
+ QVERIFY(ctx2.create());
+ }
+
+ QVERIFY(ctx2.makeCurrent(surface.data()));
+
+ QOpenGLFramebufferObject fbo2(size);
+ QVERIFY(fbo2.bind());
+
+ QOpenGLPaintDevice device2(size);
+
+ QVERIFY(p.begin(&device2));
+ drawColoredRects(&p, size);
+ p.end();
+
+ QImage img2 = fbo2.toImage();
+
+ QFUZZY_COMPARE_IMAGES(img1, img2);
+}
+
void tst_QOpenGL::aboutToBeDestroyed()
{
QWindow window;