aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLorn Potter <lorn.potter@gmail.com>2017-12-01 15:50:30 +1000
committerLorn Potter <lorn.potter@gmail.com>2018-01-04 20:15:52 +0000
commit62d07125620e787e7461edc5cfd4aa4287f26847 (patch)
treeced38f7a6c4c6976c8d31d31001691d12e029ab6
parent1dbe0acecbc286b6df25fe2a9c4a373fa0d6b11e (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.h1
-rw-r--r--src/imports/shapes/qquickshapegenericrenderer.cpp9
-rw-r--r--src/plugins/plugins.pro2
-rw-r--r--src/qml/animations/qabstractanimationjob.cpp3
-rw-r--r--src/qml/qml/ftw/qqmlthread.cpp19
-rw-r--r--src/qml/qml/qqmlimport.cpp13
-rw-r--r--src/qml/qml/qqmltypeloader.cpp20
-rw-r--r--src/qml/qml/v8/qv8engine.cpp2
-rw-r--r--src/qml/qtqmlglobal.h2
-rw-r--r--src/quick/items/qquickwindow.cpp2
-rw-r--r--src/quick/items/qquickwindowattached.cpp1
-rw-r--r--src/quick/items/qquickwindowmodule_p.h2
-rw-r--r--src/quick/scenegraph/qsgcontextplugin.cpp5
-rw-r--r--src/quick/scenegraph/qsgrenderloop.cpp3
-rw-r--r--tools/tools.pro2
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
}