diff options
author | Lorn Potter <lorn.potter@gmail.com> | 2017-12-01 15:50:30 +1000 |
---|---|---|
committer | Lorn Potter <lorn.potter@gmail.com> | 2018-01-04 20:15:52 +0000 |
commit | 62d07125620e787e7461edc5cfd4aa4287f26847 (patch) | |
tree | ced38f7a6c4c6976c8d31d31001691d12e029ab6 | |
parent | 1dbe0acecbc286b6df25fe2a9c4a373fa0d6b11e (diff) |
wasm: get declarative building and running for webassembly
One thread
Change-Id: Iab9bd20eb5951c7b0fe0b6f48f1f14ea7560d8f7
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
-rw-r--r-- | src/3rdparty/masm/wtf/Platform.h | 1 | ||||
-rw-r--r-- | src/imports/shapes/qquickshapegenericrenderer.cpp | 9 | ||||
-rw-r--r-- | src/plugins/plugins.pro | 2 | ||||
-rw-r--r-- | src/qml/animations/qabstractanimationjob.cpp | 3 | ||||
-rw-r--r-- | src/qml/qml/ftw/qqmlthread.cpp | 19 | ||||
-rw-r--r-- | src/qml/qml/qqmlimport.cpp | 13 | ||||
-rw-r--r-- | src/qml/qml/qqmltypeloader.cpp | 20 | ||||
-rw-r--r-- | src/qml/qml/v8/qv8engine.cpp | 2 | ||||
-rw-r--r-- | src/qml/qtqmlglobal.h | 2 | ||||
-rw-r--r-- | src/quick/items/qquickwindow.cpp | 2 | ||||
-rw-r--r-- | src/quick/items/qquickwindowattached.cpp | 1 | ||||
-rw-r--r-- | src/quick/items/qquickwindowmodule_p.h | 2 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgcontextplugin.cpp | 5 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgrenderloop.cpp | 3 | ||||
-rw-r--r-- | tools/tools.pro | 2 |
15 files changed, 66 insertions, 20 deletions
diff --git a/src/3rdparty/masm/wtf/Platform.h b/src/3rdparty/masm/wtf/Platform.h index 7f2023a68a..3d7086b585 100644 --- a/src/3rdparty/masm/wtf/Platform.h +++ b/src/3rdparty/masm/wtf/Platform.h @@ -157,6 +157,7 @@ || defined(_M_IX86) \ || defined(_X86_) \ || defined(__THW_INTEL) + #define WTF_CPU_X86 1 #endif diff --git a/src/imports/shapes/qquickshapegenericrenderer.cpp b/src/imports/shapes/qquickshapegenericrenderer.cpp index 8131f02f1a..44253a2596 100644 --- a/src/imports/shapes/qquickshapegenericrenderer.cpp +++ b/src/imports/shapes/qquickshapegenericrenderer.cpp @@ -278,6 +278,7 @@ void QQuickShapeGenericRenderer::setAsyncCallback(void (*callback)(void *), void m_asyncCallbackData = data; } +#ifndef QT_NO_THREAD static QThreadPool *pathWorkThreadPool = nullptr; static void deletePathWorkThreadPool() @@ -285,6 +286,7 @@ static void deletePathWorkThreadPool() delete pathWorkThreadPool; pathWorkThreadPool = nullptr; } +#endif void QQuickShapeGenericRenderer::endSync(bool async) { @@ -311,13 +313,14 @@ void QQuickShapeGenericRenderer::endSync(bool async) continue; } +#ifndef QT_NO_THREAD if (async && !pathWorkThreadPool) { qAddPostRoutine(deletePathWorkThreadPool); pathWorkThreadPool = new QThreadPool; const int idealCount = QThread::idealThreadCount(); pathWorkThreadPool->setMaxThreadCount(idealCount > 0 ? idealCount * 2 : 4); } - +#endif if ((d.syncDirty & DirtyFillGeom) && d.fillColor.a) { d.path.setFillRule(d.fillRule); if (m_api == QSGRendererInterface::Unknown) @@ -348,7 +351,9 @@ void QQuickShapeGenericRenderer::endSync(bool async) r->deleteLater(); }); didKickOffAsync = true; +#ifndef QT_NO_THREAD pathWorkThreadPool->start(r); +#endif } else { triangulateFill(d.path, d.fillColor, &d.fillVertices, &d.fillIndices, &d.indexType, q_supportsElementIndexUint(m_api)); } @@ -376,7 +381,9 @@ void QQuickShapeGenericRenderer::endSync(bool async) r->deleteLater(); }); didKickOffAsync = true; +#ifndef QT_NO_THREAD pathWorkThreadPool->start(r); +#endif } else { triangulateStroke(d.path, d.pen, d.strokeColor, &d.strokeVertices, QSize(m_item->width(), m_item->height())); diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index 0afd71767e..d3a8a17cf7 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -1,5 +1,5 @@ TEMPLATE = subdirs QT_FOR_CONFIG += qml -qtConfig(qml-debug):SUBDIRS += qmltooling +!emacsripten:qtConfig(qml-debug):SUBDIRS += qmltooling qtHaveModule(quick):SUBDIRS += scenegraph diff --git a/src/qml/animations/qabstractanimationjob.cpp b/src/qml/animations/qabstractanimationjob.cpp index 1ac4925ed3..a931d733d6 100644 --- a/src/qml/animations/qabstractanimationjob.cpp +++ b/src/qml/animations/qabstractanimationjob.cpp @@ -78,7 +78,8 @@ QQmlAnimationTimer *QQmlAnimationTimer::instance(bool create) inst = animationTimer() ? animationTimer()->localData() : 0; } #else - static QAnimationTimer unifiedTimer; + Q_UNUSED(create) + static QQmlAnimationTimer unifiedTimer; inst = &unifiedTimer; #endif return inst; diff --git a/src/qml/qml/ftw/qqmlthread.cpp b/src/qml/qml/ftw/qqmlthread.cpp index cae7088840..bf62d7a99a 100644 --- a/src/qml/qml/ftw/qqmlthread.cpp +++ b/src/qml/qml/ftw/qqmlthread.cpp @@ -105,6 +105,9 @@ void QQmlThreadPrivate::triggerMainEvent() { Q_ASSERT(q->isThisThread()); QCoreApplication::postEvent(&m_mainObject, new QEvent(QEvent::User)); +#ifdef Q_OS_HTML5 + QCoreApplication::processEvents(); +#endif } // Trigger even in thread. Must be called from main thread. @@ -112,6 +115,9 @@ void QQmlThreadPrivate::triggerThreadEvent() { Q_ASSERT(!q->isThisThread()); QCoreApplication::postEvent(this, new QEvent(QEvent::User)); +#ifdef Q_OS_HTML5 + QCoreApplication::processEvents(); +#endif } bool QQmlThreadPrivate::MainObject::event(QEvent *e) @@ -316,11 +322,16 @@ void QQmlThread::internalCallMethodInThread(Message *message) bool wasEmpty = d->threadList.isEmpty(); d->threadList.append(message); + +#ifdef Q_OS_HTML5 + d->mainSync = message; +#endif if (wasEmpty && d->m_threadProcessing == false) d->triggerThreadEvent(); - d->m_mainThreadWaiting = true; +#ifndef Q_OS_HTML5 + d->m_mainThreadWaiting = true; do { if (d->mainSync) { QQmlThread::Message *message = d->mainSync; @@ -334,7 +345,7 @@ void QQmlThread::internalCallMethodInThread(Message *message) d->wait(); } } while (d->mainSync || !d->threadList.isEmpty()); - +#endif d->m_mainThreadWaiting = false; d->unlock(); } @@ -396,8 +407,10 @@ void QQmlThread::waitForNextMessage() d->lock(); Q_ASSERT(d->m_mainThreadWaiting == false); +#ifdef Q_OS_HTML5 + d->triggerThreadEvent(); +#endif d->m_mainThreadWaiting = true; - if (d->mainSync || !d->threadList.isEmpty()) { if (d->mainSync) { QQmlThread::Message *message = d->mainSync; diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp index a85166da65..0fbe934bb9 100644 --- a/src/qml/qml/qqmlimport.cpp +++ b/src/qml/qml/qqmlimport.cpp @@ -1274,9 +1274,8 @@ bool QQmlImportsPrivate::locateQmldir(const QString &uri, int vmaj, int vmin, QQ QQmlTypeLoader &typeLoader = QQmlEnginePrivate::get(database->engine)->typeLoader; - QStringList localImportPaths = database->importPathList(QQmlImportDatabase::Local); - // Search local import paths for a matching version + QStringList localImportPaths = database->importPathList(QQmlImportDatabase::Local); const QStringList qmlDirPaths = QQmlImports::completeQmldirPaths(uri, localImportPaths, vmaj, vmin); for (const QString &qmldirPath : qmlDirPaths) { QString absoluteFilePath = typeLoader.absoluteFilePath(qmldirPath); @@ -1731,10 +1730,16 @@ QQmlImportDatabase::QQmlImportDatabase(QQmlEngine *e) { filePluginPath << QLatin1String("."); // Search order is applicationDirPath(), qrc:/qt-project.org/imports, $QML2_IMPORT_PATH, QLibraryInfo::Qml2ImportsPath +#ifdef Q_OS_HTML5 + // Hardcode the qml imports to "qml/" relative to the app nexe. + // This should perhaps be set via Qml2Imports in qt.conf. + QString installImportsPath = QStringLiteral("qml/"); - QString installImportsPath = QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath); - addImportPath(installImportsPath); +#else + QString installImportsPath = QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath); +#endif + addImportPath(installImportsPath); // env import paths if (Q_UNLIKELY(!qEnvironmentVariableIsEmpty("QML2_IMPORT_PATH"))) { const QString envImportPath = qEnvironmentVariable("QML2_IMPORT_PATH"); diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index 55e05afdaa..451f122cb2 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -484,8 +484,9 @@ The setError() method may only be called from within a QQmlDataBlob callback. */ void QQmlDataBlob::addDependency(QQmlDataBlob *blob) { +#ifndef Q_OS_HTML5 ASSERT_CALLBACK(); - +#endif Q_ASSERT(status() != Null); if (!blob || @@ -1039,8 +1040,8 @@ void QQmlTypeLoader::doLoad(const Loader &loader, QQmlDataBlob *blob, Mode mode) qWarning("QQmlTypeLoader::doLoad(%s): %s thread", qPrintable(blob->m_url.toString()), m_thread->isThisThread()?"Compile":"Engine"); #endif - blob->startLoading(); + blob->startLoading(); if (m_thread->isThisThread()) { unlock(); loader.loadThread(this, blob); @@ -1048,7 +1049,12 @@ void QQmlTypeLoader::doLoad(const Loader &loader, QQmlDataBlob *blob, Mode mode) } else if (mode == Asynchronous) { blob->m_data.setIsAsync(true); unlock(); + +#ifndef Q_OS_HTML5 + loader.loadThread(this, blob); +#else loader.loadAsync(this, blob); +#endif lock(); } else { unlock(); @@ -1723,10 +1729,14 @@ Returns a QQmlQmldirData for \a url. The QQmlQmldirData may be cached. */ QQmlQmldirData *QQmlTypeLoader::getQmldir(const QUrl &url) { +#ifdef Q_OS_HTML5 + // ### asserts here on urls like "qml/QtQuick.2.1/qmldir", + // which are relative urls we want to load over the network. +#else Q_ASSERT(!url.isRelative() && (QQmlFile::urlToLocalFileOrQrc(url).isEmpty() || !QDir::isRelativePath(QQmlFile::urlToLocalFileOrQrc(url)))); - +#endif LockHolder<QQmlTypeLoader> holder(this); QQmlQmldirData *qmldirData = m_qmldirCache.value(url); @@ -2387,10 +2397,10 @@ bool QQmlTypeData::loadImplicitImport() void QQmlTypeData::dataReceived(const SourceCodeData &data) { m_backupSourceCode = data; - +#ifndef Q_OS_HTML5 if (tryLoadFromDiskCache()) return; - +#endif if (isError()) return; diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp index dadff819cf..624e222241 100644 --- a/src/qml/qml/v8/qv8engine.cpp +++ b/src/qml/qml/v8/qv8engine.cpp @@ -129,11 +129,13 @@ QV8Engine::QV8Engine(QJSEngine* qq) , m_xmlHttpRequestData(0) , m_listModelData(0) { +#ifndef Q_OS_HTML5 #ifdef Q_PROCESSOR_X86_32 if (!qCpuHasFeature(SSE2)) { qFatal("This program requires an X86 processor that supports SSE2 extension, at least a Pentium 4 or newer"); } #endif +#endif QML_MEMORY_SCOPE_STRING("QV8Engine::QV8Engine"); qMetaTypeId<QJSValue>(); diff --git a/src/qml/qtqmlglobal.h b/src/qml/qtqmlglobal.h index 6e92867cf5..f22eb54c43 100644 --- a/src/qml/qtqmlglobal.h +++ b/src/qml/qtqmlglobal.h @@ -51,7 +51,9 @@ # include <QtNetwork/qtnetworkglobal.h> # endif #else +//#ifndef QT_FEATURE_qml_debug # define QT_FEATURE_qml_debug -1 +//#endif #endif QT_BEGIN_NAMESPACE diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index caae188ed8..462790e1b1 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -532,6 +532,8 @@ void QQuickWindowPrivate::init(QQuickWindow *c, QQuickRenderControl *control) Q_Q(QQuickWindow); + qRegisterMetaType<QWindow::Visibility>(); + contentItem = new QQuickRootItem; QQml_setParent_noEvent(contentItem, c); QQmlEngine::setObjectOwnership(contentItem, QQmlEngine::CppOwnership); diff --git a/src/quick/items/qquickwindowattached.cpp b/src/quick/items/qquickwindowattached.cpp index ae62a7a496..d3835ed45c 100644 --- a/src/quick/items/qquickwindowattached.cpp +++ b/src/quick/items/qquickwindowattached.cpp @@ -116,7 +116,6 @@ void QQuickWindowAttached::windowChange(QQuickWindow *window) if (!window) return; - // QQuickWindowQmlImpl::visibilityChanged also exists, and window might even // be QQuickWindowQmlImpl, but that's not what we are connecting to. // So this is actual window state rather than a buffered or as-requested one. diff --git a/src/quick/items/qquickwindowmodule_p.h b/src/quick/items/qquickwindowmodule_p.h index e7033e9b8d..4a6f315d58 100644 --- a/src/quick/items/qquickwindowmodule_p.h +++ b/src/quick/items/qquickwindowmodule_p.h @@ -58,6 +58,8 @@ QT_BEGIN_NAMESPACE +Q_DECLARE_METATYPE(QWindow::Visibility) + class QQuickWindowQmlImplPrivate; class Q_QUICK_PRIVATE_EXPORT QQuickWindowQmlImpl : public QQuickWindow, public QQmlParserStatus diff --git a/src/quick/scenegraph/qsgcontextplugin.cpp b/src/quick/scenegraph/qsgcontextplugin.cpp index 6583883d0c..1c2550d197 100644 --- a/src/quick/scenegraph/qsgcontextplugin.cpp +++ b/src/quick/scenegraph/qsgcontextplugin.cpp @@ -137,9 +137,10 @@ QSGAdaptationBackendData *contextFactory() && !QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)) { requestedBackend = QString::fromLocal8Bit("software"); } - +#ifdef Q_OS_HTML5 + requestedBackend = QString::fromLocal8Bit("software"); +#endif if (!requestedBackend.isEmpty()) { - qCDebug(QSG_LOG_INFO) << "Loading backend" << requestedBackend; // First look for a built-in adaptation. for (QSGContextFactoryInterface *builtInBackend : qAsConst(backendData->builtIns)) { diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp index 88899c400c..04c19a5501 100644 --- a/src/quick/scenegraph/qsgrenderloop.cpp +++ b/src/quick/scenegraph/qsgrenderloop.cpp @@ -201,6 +201,8 @@ QSGRenderLoop *QSGRenderLoop::instance() loopType = ThreadedRenderLoop; else loopType = WindowsRenderLoop; +#elif defined(Q_OS_HTML5) + loopType = BasicRenderLoop; #else if (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedOpenGL)) loopType = ThreadedRenderLoop; @@ -406,7 +408,6 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window) if (profileFrames) renderTimer.start(); Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishFrame); - cd->polishItems(); if (profileFrames) diff --git a/tools/tools.pro b/tools/tools.pro index 20a3600fb8..0c9fa34601 100644 --- a/tools/tools.pro +++ b/tools/tools.pro @@ -26,7 +26,7 @@ qtConfig(commandlineparser): SUBDIRS += qmlcachegen } qtHaveModule(widgets): SUBDIRS += qmleasing } - qtHaveModule(qmltest): SUBDIRS += qmltestrunner + !emscripten:qtHaveModule(qmltest): SUBDIRS += qmltestrunner qtConfig(private_tests): SUBDIRS += qmljs } |