diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2020-06-22 11:52:20 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2020-06-22 16:10:35 +0200 |
commit | fdba8facd0093e3dbc18eaefa08a864d15606909 (patch) | |
tree | 0da1d02e76aa1a81f94ad3e05af7b9483e1538c2 /tests/auto/quick | |
parent | 6ca0145f068d83099ced536f2b0e62b5c2839a8b (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.cpp | 161 |
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" |