diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/qml/Info.plist | 2 | ||||
-rw-r--r-- | tools/qml/main.cpp | 82 | ||||
-rw-r--r-- | tools/qmlscene/main.cpp | 112 |
3 files changed, 161 insertions, 35 deletions
diff --git a/tools/qml/Info.plist b/tools/qml/Info.plist index 42d074a3af..567c5bf8fd 100644 --- a/tools/qml/Info.plist +++ b/tools/qml/Info.plist @@ -2,6 +2,8 @@ <!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd"> <plist version="0.1"> <dict> + <key>NSPrincipalClass</key> + <string>NSApplication</string> <key>CFBundleIconFile</key> <string>@ICON@</string> <key>CFBundleIdentifier</key> diff --git a/tools/qml/main.cpp b/tools/qml/main.cpp index ea601ba946..206788c061 100644 --- a/tools/qml/main.cpp +++ b/tools/qml/main.cpp @@ -39,6 +39,8 @@ #include <QGuiApplication> #include <QWindow> #include <QFileOpenEvent> +#include <QOpenGLContext> +#include <QOpenGLFunctions> #ifdef QT_WIDGETS_LIB #include <QApplication> #endif // QT_WIDGETS_LIB @@ -56,6 +58,7 @@ #include <QStandardPaths> #include <QTranslator> #include <QtGlobal> +#include <QLibraryInfo> #include <qqml.h> #include <qqmldebug.h> #include <private/qabstractanimation_p.h> @@ -73,6 +76,7 @@ static Config *conf = 0; static QQmlApplicationEngine *qae = 0; static int exitTimerId = -1; +bool verboseMode = false; static void loadConf(const QString &override, bool quiet) // Terminates app on failure { @@ -101,6 +105,7 @@ static void loadConf(const QString &override, bool quiet) // Terminates app on f } if (!quiet) { + printf("qml: %s\n", QLibraryInfo::build()); if (builtIn) printf("qml: Using built-in configuration.\n"); else @@ -121,20 +126,6 @@ static void loadConf(const QString &override, bool quiet) // Terminates app on f } } -void contain(QObject *o, const QUrl &containPath) -{ - QQmlComponent c(qae, containPath); - QObject *o2 = c.create(); - if (!o2) - return; - bool success = false; - int idx; - if ((idx = o2->metaObject()->indexOfProperty("containedObject")) != -1) - success = o2->metaObject()->property(idx).write(o2, QVariant::fromValue<QObject*>(o)); - if (!success) - o->setParent(o2); //Set QObject parent, and assume container will react as needed -} - #ifdef QT_GUI_LIB void noFilesGiven(); @@ -188,6 +179,9 @@ public: bool earlyExit; private: + void contain(QObject *o, const QUrl &containPath); + void checkForWindow(QObject *o); + int expect; bool haveOne; @@ -195,6 +189,7 @@ public Q_SLOTS: void checkFinished(QObject *o) { if (o) { + checkForWindow(o); haveOne = true; if (conf && qae) foreach (PartialScene *ps, conf->completers) @@ -214,8 +209,56 @@ public Q_SLOTS: //Will be checked before calling exec() earlyExit = true; } +#ifdef QT_GUI_LIB + void onOpenGlContextCreated(QOpenGLContext *context); +#endif }; +void LoadWatcher::contain(QObject *o, const QUrl &containPath) +{ + QQmlComponent c(qae, containPath); + QObject *o2 = c.create(); + if (!o2) + return; + checkForWindow(o2); + bool success = false; + int idx; + if ((idx = o2->metaObject()->indexOfProperty("containedObject")) != -1) + success = o2->metaObject()->property(idx).write(o2, QVariant::fromValue<QObject*>(o)); + if (!success) + o->setParent(o2); //Set QObject parent, and assume container will react as needed +} + +void LoadWatcher::checkForWindow(QObject *o) +{ +#ifdef QT_GUI_LIB + if (verboseMode && o->isWindowType() && o->inherits("QQuickWindow")) { + connect(o, SIGNAL(openglContextCreated(QOpenGLContext*)), + this, SLOT(onOpenGlContextCreated(QOpenGLContext*))); + } +#else + Q_UNUSED(o) +#endif // QT_GUI_LIB +} + +#ifdef QT_GUI_LIB +void LoadWatcher::onOpenGlContextCreated(QOpenGLContext *context) +{ + context->makeCurrent(qobject_cast<QWindow *>(sender())); + QOpenGLFunctions functions(context); + QByteArray output = "Vendor : "; + output += reinterpret_cast<const char *>(functions.glGetString(GL_VENDOR)); + output += "\nRenderer: "; + output += reinterpret_cast<const char *>(functions.glGetString(GL_RENDERER)); + output += "\nVersion : "; + output += reinterpret_cast<const char *>(functions.glGetString(GL_VERSION)); + output += "\nLanguage: "; + output += reinterpret_cast<const char *>(functions.glGetString(GL_SHADING_LANGUAGE_VERSION)); + puts(output.constData()); + context->doneCurrent(); +} +#endif // QT_GUI_LIB + void quietMessageHandler(QtMsgType type, const QMessageLogContext &ctxt, const QString &msg) { Q_UNUSED(ctxt); @@ -251,7 +294,6 @@ QmlApplicationType applicationType = QmlApplicationTypeCore; QmlApplicationType applicationType = QmlApplicationTypeGui; #endif // QT_GUI_LIB bool quietMode = false; -bool verboseMode = false; void printVersion() { printf("qml binary version "); @@ -286,6 +328,10 @@ void printUsage() printf("\t-f [file] .................... Load the given file as a QML file.\n"); printf("\t-config [file] ............... Load the given file as the configuration file.\n"); printf("\t-- ........................... Arguments after this one are ignored by the launcher, but may be used within the QML application.\n"); + printf("\tGL options:\n"); + printf("\t-desktop.......................Force use of desktop GL (AA_UseDesktopOpenGL)\n"); + printf("\t-gles..........................Force use of GLES (AA_UseOpenGLES)\n"); + printf("\t-software......................Force use of software rendering (AA_UseOpenGLES)\n"); printf("\tDebugging options:\n"); printf("\t-verbose ..................... Print information about what qml is doing, like specific file urls being loaded.\n"); printf("\t-translation [file] .......... Load the given file as the translations file.\n"); @@ -451,6 +497,12 @@ int main(int argc, char *argv[]) continue;//Invalid usage, but just ignore it dummyDir = argList[i+1]; i++; + } else if (arg == QLatin1String("-gles")) { + QCoreApplication::setAttribute(Qt::AA_UseOpenGLES); + } else if (arg == QLatin1String("-software")) { + QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL); + } else if (arg == QLatin1String("-desktop")) { + QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL); } else { files << arg; } diff --git a/tools/qmlscene/main.cpp b/tools/qmlscene/main.cpp index b8920cd853..fe01b92244 100644 --- a/tools/qmlscene/main.cpp +++ b/tools/qmlscene/main.cpp @@ -40,6 +40,7 @@ #include <QtCore/qtextstream.h> #include <QtGui/QGuiApplication> +#include <QtGui/QOpenGLFunctions> #include <QtQml/qqml.h> #include <QtQml/qqmlengine.h> @@ -148,8 +149,11 @@ struct Options , quitImmediately(false) , resizeViewToRootItem(false) , multisample(false) - , contextSharing(true) + , verbose(false) { + // QtWebEngine needs a shared context in order for the GPU thread to + // upload textures. + applicationAttributes.append(Qt::AA_ShareOpenGLContexts); } QUrl file; @@ -164,7 +168,8 @@ struct Options bool quitImmediately; bool resizeViewToRootItem; bool multisample; - bool contextSharing; + bool verbose; + QVector<Qt::ApplicationAttribute> applicationAttributes; QString translationFile; }; @@ -340,23 +345,77 @@ static void usage() puts("Usage: qmlscene [options] <filename>"); puts(" "); puts(" Options:"); - puts(" --maximized ............................... Run maximized"); - puts(" --fullscreen .............................. Run fullscreen"); - puts(" --transparent ............................. Make the window transparent"); - puts(" --multisample ............................. Enable multisampling (OpenGL anti-aliasing)"); - puts(" --no-version-detection .................... Do not try to detect the version of the .qml file"); - puts(" --slow-animations ......................... Run all animations in slow motion"); - puts(" --resize-to-root .......................... Resize the window to the size of the root item"); - puts(" --quit .................................... Quit immediately after starting"); - puts(" --disable-context-sharing ................. Disable the use of a shared GL context for QtQuick Windows"); - puts(" -I <path> ................................. Add <path> to the list of import paths"); - puts(" -P <path> ................................. Add <path> to the list of plugin paths"); - puts(" -translation <translationfile> ............ Set the language to run in"); + puts(" --maximized ...................... Run maximized"); + puts(" --fullscreen ..................... Run fullscreen"); + puts(" --transparent .................... Make the window transparent"); + puts(" --multisample .................... Enable multisampling (OpenGL anti-aliasing)"); + puts(" --no-version-detection ........... Do not try to detect the version of the .qml file"); + puts(" --slow-animations ................ Run all animations in slow motion"); + puts(" --resize-to-root ................. Resize the window to the size of the root item"); + puts(" --quit ........................... Quit immediately after starting"); + puts(" --disable-context-sharing ........ Disable the use of a shared GL context for QtQuick Windows\n" + " .........(remove AA_ShareOpenGLContexts)"); + puts(" --desktop..........................Force use of desktop GL (AA_UseDesktopOpenGL)"); + puts(" --gles.............................Force use of GLES (AA_UseOpenGLES)"); + puts(" --software.........................Force use of software rendering (AA_UseOpenGLES)"); + puts(" --verbose..........................Print version and graphical diagnostics for the run-time"); + puts(" -I <path> ........................ Add <path> to the list of import paths"); + puts(" -P <path> ........................ Add <path> to the list of plugin paths"); + puts(" -translation <translationfile> ... Set the language to run in"); puts(" "); exit(1); } +// Listen on GL context creation of the QQuickWindow in order to print diagnostic output. +class DiagnosticGlContextCreationListener : public QObject { + Q_OBJECT +public: + explicit DiagnosticGlContextCreationListener(QQuickWindow *window) : QObject(window) + { + connect(window, &QQuickWindow::openglContextCreated, + this, &DiagnosticGlContextCreationListener::onOpenGlContextCreated); + } + +private slots: + void onOpenGlContextCreated(QOpenGLContext *context) + { + context->makeCurrent(qobject_cast<QQuickWindow *>(parent())); + QOpenGLFunctions functions(context); + QByteArray output = "Vendor : "; + output += reinterpret_cast<const char *>(functions.glGetString(GL_VENDOR)); + output += "\nRenderer: "; + output += reinterpret_cast<const char *>(functions.glGetString(GL_RENDERER)); + output += "\nVersion : "; + output += reinterpret_cast<const char *>(functions.glGetString(GL_VERSION)); + output += "\nLanguage: "; + output += reinterpret_cast<const char *>(functions.glGetString(GL_SHADING_LANGUAGE_VERSION)); + puts(output.constData()); + context->doneCurrent(); + deleteLater(); + } +}; + +static void setWindowTitle(bool verbose, const QObject *topLevel, QWindow *window) +{ + const QString oldTitle = window->title(); + QString newTitle = oldTitle; + if (newTitle.isEmpty()) { + newTitle = QLatin1String("qmlscene"); + if (!qobject_cast<const QWindow *>(topLevel) && !topLevel->objectName().isEmpty()) + newTitle += QLatin1String(": ") + topLevel->objectName(); + } + if (verbose) { + newTitle += QLatin1String(" [Qt ") + QLatin1String(QT_VERSION_STR) + QLatin1Char(' ') + + QGuiApplication::platformName() + QLatin1Char(' '); + newTitle += QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL + ? QLatin1String("GL") : QLatin1String("GLES"); + newTitle += QLatin1Char(']'); + } + if (oldTitle != newTitle) + window->setTitle(newTitle); +} + int main(int argc, char ** argv) { Options options; @@ -389,7 +448,15 @@ int main(int argc, char ** argv) else if (lowerArgument == QLatin1String("--multisample")) options.multisample = true; else if (lowerArgument == QLatin1String("--disable-context-sharing")) - options.contextSharing = false; + options.applicationAttributes.removeAll(Qt::AA_ShareOpenGLContexts); + else if (lowerArgument == QLatin1String("--gles")) + options.applicationAttributes.append(Qt::AA_UseOpenGLES); + else if (lowerArgument == QLatin1String("--software")) + options.applicationAttributes.append(Qt::AA_UseSoftwareOpenGL); + else if (lowerArgument == QLatin1String("--desktop")) + options.applicationAttributes.append(Qt::AA_UseDesktopOpenGL); + else if (lowerArgument == QLatin1String("--verbose")) + options.verbose = true; else if (lowerArgument == QLatin1String("-i") && i + 1 < argc) imports.append(QString::fromLatin1(argv[++i])); else if (lowerArgument == QLatin1String("-p") && i + 1 < argc) @@ -402,9 +469,8 @@ int main(int argc, char ** argv) } } - // QtWebEngine needs a shared context in order for the GPU thread to - // upload textures. - QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts, options.contextSharing); + foreach (Qt::ApplicationAttribute a, options.applicationAttributes) + QCoreApplication::setAttribute(a); #ifdef QT_WIDGETS_LIB QApplication app(argc, argv); #else @@ -445,6 +511,9 @@ int main(int argc, char ** argv) int exitCode = 0; + if (options.verbose) + puts(QLibraryInfo::build()); + if (!options.file.isEmpty()) { if (!options.versionDetection || checkVersion(options.file)) { #ifndef QT_NO_TRANSLATION @@ -487,8 +556,6 @@ int main(int argc, char ** argv) QQuickView* qxView = new QQuickView(&engine, NULL); window.reset(qxView); // Set window default properties; the qml can still override them - QString oname = contentItem->objectName(); - window->setTitle(oname.isEmpty() ? QString::fromLatin1("qmlscene") : QString::fromLatin1("qmlscene: ") + oname); if (options.resizeViewToRootItem) qxView->setResizeMode(QQuickView::SizeViewToRootObject); else @@ -498,6 +565,9 @@ int main(int argc, char ** argv) } if (window) { + setWindowTitle(options.verbose, topLevel, window.data()); + if (options.verbose) + new DiagnosticGlContextCreationListener(window.data()); QSurfaceFormat surfaceFormat = window->requestedFormat(); if (options.multisample) surfaceFormat.setSamples(16); @@ -539,3 +609,5 @@ int main(int argc, char ** argv) return exitCode; } + +#include "main.moc" |