aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/quick
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2020-06-22 11:52:20 +0200
committerLaszlo Agocs <laszlo.agocs@qt.io>2020-06-22 16:10:35 +0200
commitfdba8facd0093e3dbc18eaefa08a864d15606909 (patch)
tree0da1d02e76aa1a81f94ad3e05af7b9483e1538c2 /tests/auto/quick
parent6ca0145f068d83099ced536f2b0e62b5c2839a8b (diff)
tst_qquickwindow: Add basic rendererInterface test
And remove some dead code. Change-Id: Ic49acb1241020dea4ebff829d335d3b98716bbc0 Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'tests/auto/quick')
-rw-r--r--tests/auto/quick/qquickwindow/tst_qquickwindow.cpp161
1 files changed, 110 insertions, 51 deletions
diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
index a4a3d55dcf..715456a648 100644
--- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
+++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
@@ -45,8 +45,12 @@
#include <private/qquickwindow_p.h>
#include <private/qguiapplication_p.h>
#include <QRunnable>
-#include <QOpenGLFunctions>
#include <QSGRendererInterface>
+#include <QQuickRenderControl>
+#include <functional>
+#if QT_CONFIG(opengl)
+#include <QOpenGLContext>
+#endif
Q_LOGGING_CATEGORY(lcTests, "qt.quick.tests")
@@ -485,6 +489,8 @@ private slots:
void testShortCut();
#endif
+ void rendererInterface();
+
private:
QTouchDevice *touchDevice;
QTouchDevice *touchDeviceWithVelocity;
@@ -2493,29 +2499,6 @@ public:
}
static int deleted;
};
-#if QT_CONFIG(opengl)
-class GlRenderJob : public QRunnable
-{
-public:
- GlRenderJob(GLubyte *buf) : readPixel(buf), mutex(nullptr), condition(nullptr) {}
- ~GlRenderJob() {}
- void run() {
- QOpenGLContext::currentContext()->functions()->glClearColor(1.0f, 0, 0, 1.0f);
- QOpenGLContext::currentContext()->functions()->glClear(GL_COLOR_BUFFER_BIT);
- QOpenGLContext::currentContext()->functions()->glReadPixels(0, 0, 1, 1, GL_RGBA,
- GL_UNSIGNED_BYTE,
- (void *)readPixel);
- if (mutex) {
- mutex->lock();
- condition->wakeOne();
- mutex->unlock();
- }
- }
- GLubyte *readPixel;
- QMutex *mutex;
- QWaitCondition *condition;
-};
-#endif
int RenderJob::deleted = 0;
void tst_qquickwindow::testRenderJob()
@@ -2563,33 +2546,6 @@ void tst_qquickwindow::testRenderJob()
QQuickWindow::NoStage);
QTRY_COMPARE(RenderJob::deleted, 1);
QCOMPARE(completedJobs.size(), 1);
-
-#if QT_CONFIG(opengl)
- if (window.rendererInterface()->graphicsApi() == QSGRendererInterface::OpenGL) {
- // Do a synchronized GL job.
- GLubyte readPixel[4] = {0, 0, 0, 0};
- GlRenderJob *glJob = new GlRenderJob(readPixel);
- QOpenGLContext *ctx = static_cast<QOpenGLContext *>(window.rendererInterface()->getResource(
- &window, QSGRendererInterface::OpenGLContextResource));
- QVERIFY(ctx);
- if (ctx->thread() != QThread::currentThread()) {
- QMutex mutex;
- QWaitCondition condition;
- glJob->mutex = &mutex;
- glJob->condition = &condition;
- mutex.lock();
- window.scheduleRenderJob(glJob, QQuickWindow::NoStage);
- condition.wait(&mutex);
- mutex.unlock();
- } else {
- window.scheduleRenderJob(glJob, QQuickWindow::NoStage);
- }
- QCOMPARE(int(readPixel[0]), 255);
- QCOMPARE(int(readPixel[1]), 0);
- QCOMPARE(int(readPixel[2]), 0);
- QCOMPARE(int(readPixel[3]), 255);
- }
-#endif
}
// Verify that jobs are deleted when window is not rendered at all
@@ -3636,6 +3592,109 @@ void tst_qquickwindow::testShortCut()
}
#endif
+void tst_qquickwindow::rendererInterface()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.loadUrl(testFileUrl("Headless.qml"));
+ QObject *created = component.create();
+ QScopedPointer<QObject> cleanup(created);
+
+ QQuickWindow *window = qobject_cast<QQuickWindow*>(created);
+ QVERIFY(window);
+ window->setTitle(QTest::currentTestFunction());
+ window->show();
+
+ QVERIFY(QTest::qWaitForWindowExposed(window));
+ QVERIFY(window->isSceneGraphInitialized());
+ QVERIFY(window->rendererInterface());
+
+ QSGRendererInterface *rif = window->rendererInterface();
+ QVERIFY(rif->graphicsApi() != QSGRendererInterface::Unknown);
+
+ // Verify the essential integration points used by Quick3D.
+ if (QSGRendererInterface::isApiRhiBased(rif->graphicsApi())) {
+ QVERIFY(rif->getResource(window, QSGRendererInterface::RhiResource));
+ QVERIFY(rif->getResource(window, QSGRendererInterface::RhiSwapchainResource));
+ // the rendercontrol specific objects should not be present for an on-screen window
+ QVERIFY(!rif->getResource(window, QSGRendererInterface::RhiRedirectCommandBuffer));
+ QVERIFY(!rif->getResource(window, QSGRendererInterface::RhiRedirectRenderTarget));
+ }
+
+ // Now, depending on the graphics API, verify the native objects that are
+ // most common in applications that integrate native rendering code. Check
+ // only the globally available ones (that are available whenever the
+ // scenegraph is initialized, not just during recording a frame)
+ switch (rif->graphicsApi()) {
+ case QSGRendererInterface::OpenGLRhi:
+ QVERIFY(rif->getResource(window, QSGRendererInterface::OpenGLContextResource));
+#if QT_CONFIG(opengl)
+ {
+ QOpenGLContext *ctx = static_cast<QOpenGLContext *>(rif->getResource(window, QSGRendererInterface::OpenGLContextResource));
+ QVERIFY(ctx->isValid());
+ }
+#endif
+ break;
+ case QSGRendererInterface::Direct3D11Rhi:
+ QVERIFY(rif->getResource(window, QSGRendererInterface::DeviceResource));
+ QVERIFY(rif->getResource(window, QSGRendererInterface::DeviceContextResource));
+ break;
+ case QSGRendererInterface::VulkanRhi:
+ QVERIFY(rif->getResource(window, QSGRendererInterface::DeviceResource));
+ QVERIFY(rif->getResource(window, QSGRendererInterface::PhysicalDeviceResource));
+ QVERIFY(rif->getResource(window, QSGRendererInterface::VulkanInstanceResource));
+#if QT_CONFIG(vulkan)
+ QCOMPARE(rif->getResource(window, QSGRendererInterface::VulkanInstanceResource), window->vulkanInstance());
+#endif
+ QVERIFY(rif->getResource(window, QSGRendererInterface::CommandQueueResource));
+ break;
+ case QSGRendererInterface::MetalRhi:
+ QVERIFY(rif->getResource(window, QSGRendererInterface::DeviceResource));
+ QVERIFY(rif->getResource(window, QSGRendererInterface::CommandQueueResource));
+ break;
+ default:
+ break;
+ }
+
+ // Now the objects that are available only when preparing a frame.
+ if (QSGRendererInterface::isApiRhiBased(rif->graphicsApi())) {
+ bool ok[4] = { false, false, false, false };
+ auto f = [&ok, window](int idx) {
+ QSGRendererInterface *rif = window->rendererInterface();
+ if (rif) {
+ ok[idx] = true;
+ switch (rif->graphicsApi()) {
+ case QSGRendererInterface::VulkanRhi:
+ if (!rif->getResource(window, QSGRendererInterface::CommandListResource))
+ ok[idx] = false;
+ if (!rif->getResource(window, QSGRendererInterface::RenderPassResource))
+ ok[idx] = false;
+ break;
+ case QSGRendererInterface::MetalRhi:
+ if (!rif->getResource(window, QSGRendererInterface::CommandListResource))
+ ok[idx] = false;
+ if (!rif->getResource(window, QSGRendererInterface::CommandEncoderResource))
+ ok[idx] = false;
+ break;
+ default:
+ break;
+ }
+ }
+ };
+ // Also tests if all 4 signals are emitted as expected.
+ QObject::connect(window, &QQuickWindow::beforeRendering, window, std::bind(f, 0), Qt::DirectConnection);
+ QObject::connect(window, &QQuickWindow::beforeRenderPassRecording, window, std::bind(f, 1), Qt::DirectConnection);
+ QObject::connect(window, &QQuickWindow::afterRenderPassRecording, window, std::bind(f, 2), Qt::DirectConnection);
+ QObject::connect(window, &QQuickWindow::afterRendering, window, std::bind(f, 3), Qt::DirectConnection);
+ window->grabWindow();
+ QVERIFY(ok[0]);
+ QVERIFY(ok[1]);
+ QVERIFY(ok[2]);
+ QVERIFY(ok[3]);
+ }
+
+}
+
QTEST_MAIN(tst_qquickwindow)
#include "tst_qquickwindow.moc"