diff options
Diffstat (limited to 'src/Runtime/ogl-runtime/src/qmlstreamer')
16 files changed, 1705 insertions, 0 deletions
diff --git a/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsincubationcontroller.h b/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsincubationcontroller.h new file mode 100644 index 00000000..733037c6 --- /dev/null +++ b/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsincubationcontroller.h @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QCoreApplication> +#include <QGuiApplication> +#include <QQmlComponent> +#include <QQuickItem> +#include <QQmlIncubationController> +#include <QScreen> + +class Q3DSIncubationController : public QObject, public QQmlIncubationController +{ + Q_OBJECT +public: + explicit Q3DSIncubationController(QObject *parent = nullptr) + : QObject(parent) + , m_incubationTime(std::max(1, int(333 / QGuiApplication::primaryScreen()->refreshRate()))) + { + startTimer(QGuiApplication::primaryScreen()->refreshRate()); + } + + void timerEvent(QTimerEvent *) Q_DECL_OVERRIDE + { + incubateFor(m_incubationTime); + } + +private: + const int m_incubationTime; +}; diff --git a/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlstream.cpp b/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlstream.cpp new file mode 100644 index 00000000..e1b9e857 --- /dev/null +++ b/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlstream.cpp @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "q3dsqmlstream.h" + +/*! + \qmltype QmlStream + \instantiates Q3DSQmlStream + \inqmlmodule Qt3DStudio + \ingroup OpenGLRuntime + \brief Allows streaming of QML as subpresentation. + + \sa Studio3D, Presentation, SubPresentation +*/ +/*! + \class Q3DSQmlStream + \inmodule OpenGLRuntime + \since Qt 3D Studio 2.0 + \brief Allows streaming of QML as subpresentation. + \param parent + */ + +/*! + * \brief Q3DSQmlStream::Q3DSQmlStream Constructor + * \param parent Optional parent object. + */ +Q3DSQmlStream::Q3DSQmlStream(QObject *parent) + : QObject(parent) + , m_item(nullptr) +{ +} + +/*! + * \brief Q3DSQmlStream::~Q3DSQmlStream Destructor. + */ +Q3DSQmlStream::~Q3DSQmlStream() +{ +} + +/*! + * \qmlproperty string QmlStream::presentationId + * Contains the presentation id of this subpresentation. + */ +/*! + * \property Q3DSQmlStream::presentationId + * Contains the presentation id of this subpresentation. + */ +QString Q3DSQmlStream::presentationId() const +{ + return m_presentationId; +} + +/*! + * \qmlproperty Item QmlStream::item + * Contains the Item to be streamed as subpresentation. + */ +/*! + * \property Q3DSQmlStream::item + * Contains the QQuickItem to be streamed as subpresentation. + */ +QQuickItem *Q3DSQmlStream::item() const +{ + return m_item; +} + +void Q3DSQmlStream::setPresentationId(const QString presentationId) +{ + if (m_presentationId != presentationId) { + m_presentationId = presentationId; + emit presentationIdChanged(presentationId); + } +} + +void Q3DSQmlStream::setItem(QQuickItem *item) +{ + if (m_item != item) { + m_item = item; + emit itemChanged(item); + } +} diff --git a/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlstream.h b/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlstream.h new file mode 100644 index 00000000..74825902 --- /dev/null +++ b/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlstream.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3DS_QMLSTREAM_H +#define Q3DS_QMLSTREAM_H + +#include <QObject> + +#include "q3dsqmlstreamer_global.h" + +QT_BEGIN_NAMESPACE +class QQuickItem; +QT_END_NAMESPACE + +class Q3DS_QMLSTREAMERSHARED_EXPORT Q3DSQmlStream : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString presentationId READ presentationId WRITE setPresentationId NOTIFY presentationIdChanged) + Q_PROPERTY(QQuickItem *item READ item WRITE setItem NOTIFY itemChanged) + + Q_CLASSINFO("DefaultProperty", "item") +public: + Q3DSQmlStream(QObject *parent = nullptr); + ~Q3DSQmlStream(); + + QString presentationId() const; + QQuickItem *item() const; + +public Q_SLOTS: + void setPresentationId(const QString presentationId); + void setItem(QQuickItem *item); + +Q_SIGNALS: + void presentationIdChanged(const QString presentationId); + void itemChanged(QQuickItem *item); + +private: + QString m_presentationId; + QQuickItem *m_item; +}; + +#endif // Q3DSQMLSTREAM_H diff --git a/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlstreamer_global.h b/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlstreamer_global.h new file mode 100644 index 00000000..af12e6f0 --- /dev/null +++ b/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlstreamer_global.h @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3DS_QMLSTREAMER_GLOBAL_H +#define Q3DS_QMLSTREAMER_GLOBAL_H + +#include <QtCore/qglobal.h> + +#if defined(QMLSTREAMER_LIBRARY) +# define Q3DS_QMLSTREAMERSHARED_EXPORT Q_DECL_EXPORT +#else +# define Q3DS_QMLSTREAMERSHARED_EXPORT Q_DECL_IMPORT +#endif + +#endif // Q3DS_QMLSTREAMER_GLOBAL_H diff --git a/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlstreamerserviceimpl.cpp b/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlstreamerserviceimpl.cpp new file mode 100644 index 00000000..78c0a36a --- /dev/null +++ b/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlstreamerserviceimpl.cpp @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "q3dsqmlstreamerserviceimpl.h" + +Q3DSQmlStreamServiceImpl::Q3DSQmlStreamServiceImpl() +{ + +} + +IQ3DSQmlStreamRenderer *Q3DSQmlStreamServiceImpl::getRenderer(const char *id) +{ + if (m_producers[QString(id)]) + return m_producers[QString(id)]->getRenderer(); + return nullptr; +} + +bool Q3DSQmlStreamServiceImpl::registerProducer(IQ3DSQmlStreamProducer *producer, const char *id) +{ + m_producers[QString(id)] = producer; + return true; +} + +void Q3DSQmlStreamServiceImpl::unregisterProducer(IQ3DSQmlStreamProducer *producer) +{ + auto iter = m_producers.begin(); + for (; iter != m_producers.end(); ++iter) { + if (*iter == producer) { + m_producers.erase(iter); + return; + } + } +} + +static Q3DSQmlStreamServiceImpl *service = nullptr; +IQ3DSQmlStreamService *IQ3DSQmlStreamService::getQmlStreamService() +{ + if (!service) + service = new Q3DSQmlStreamServiceImpl(); + return service; +} diff --git a/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlstreamerserviceimpl.h b/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlstreamerserviceimpl.h new file mode 100644 index 00000000..a17bf340 --- /dev/null +++ b/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlstreamerserviceimpl.h @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3DS_QMLSTREAM_SERVICE_IMPL_H +#define Q3DS_QMLSTREAM_SERVICE_IMPL_H + +#include <QMap> + +#include "q3dsqmlstreamservice.h" + +#include "q3dsqmlstreamer_global.h" + +class Q3DSQmlStreamServiceImpl : public IQ3DSQmlStreamService +{ +public: + Q3DSQmlStreamServiceImpl(); + + IQ3DSQmlStreamRenderer *getRenderer(const char *id) override; + bool registerProducer(IQ3DSQmlStreamProducer *producer, const char *id) override; + void unregisterProducer(IQ3DSQmlStreamProducer *producer) override; +private: + + QMap<QString, IQ3DSQmlStreamProducer *> m_producers; +}; + +#endif // Q3DS_QMLSTREAMER_SERVICE_IMPL_H diff --git a/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlstreamproducer.cpp b/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlstreamproducer.cpp new file mode 100644 index 00000000..39eccb1b --- /dev/null +++ b/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlstreamproducer.cpp @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "q3dsqmlstreamproducer.h" +#include "q3dsqmlstreamrenderer.h" + +Q3DSQmlStreamProducer::Q3DSQmlStreamProducer(const QString &id, const QString &args, + QObject *parent) + : QObject(parent), m_id(id), m_args(args), m_renderer(new Q3DSQmlStreamRenderer) +{ + +} + +Q3DSQmlStreamProducer::~Q3DSQmlStreamProducer() +{ + delete m_renderer; +} + +IQ3DSQmlStreamRenderer* Q3DSQmlStreamProducer::getRenderer() +{ + return m_renderer; +} + +void Q3DSQmlStreamProducer::setPresentationItem(QQuickItem *item) +{ + m_renderer->setItem(item); +} diff --git a/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlstreamproducer.h b/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlstreamproducer.h new file mode 100644 index 00000000..d3b330d1 --- /dev/null +++ b/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlstreamproducer.h @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3DS_QMLSTREAM_PRODUCER_H +#define Q3DS_QMLSTREAM_PRODUCER_H + +#include <QObject> +#include "q3dsqmlstreamservice.h" +#include "q3dsqmlstreamer_global.h" + +QT_BEGIN_NAMESPACE +class QQuickItem; +QT_END_NAMESPACE + +class Q3DSQmlStreamRenderer; + +class Q3DS_QMLSTREAMERSHARED_EXPORT Q3DSQmlStreamProducer : public QObject, + public IQ3DSQmlStreamProducer +{ + Q_OBJECT +public: + Q3DSQmlStreamProducer(const QString &id, const QString &args, QObject *parent = nullptr); + virtual ~Q3DSQmlStreamProducer(); + + IQ3DSQmlStreamRenderer* getRenderer() override; + + void setPresentationItem(QQuickItem *item); + +private: + QString m_id; + QString m_args; + Q3DSQmlStreamRenderer *m_renderer; +}; + +#endif // Q3DS_QMLSTREAM_PRODUCER_H diff --git a/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlstreamproxy.cpp b/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlstreamproxy.cpp new file mode 100644 index 00000000..9b8550cf --- /dev/null +++ b/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlstreamproxy.cpp @@ -0,0 +1,253 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "q3dsqmlstreamservice.h" +#include "q3dsqmlstreamproxy.h" +#include "q3dsqmlstreamproducer.h" +#include "q3dsincubationcontroller.h" + +#include <QCoreApplication> +#include <QGuiApplication> +#include <QQmlComponent> +#include <QQuickItem> +#include <QQmlIncubationController> +#include <QScreen> +#include <QFileInfo> + +class Qt3DSQmlStreamEvent : public QEvent +{ +public: + Qt3DSQmlStreamEvent(const QString &id, const QString &args) + : QEvent(QEvent::User), presentationId(id), presentationArgs(args), unregister(false) + { + + } + + Qt3DSQmlStreamEvent(const QString &id) + : QEvent(QEvent::User), presentationId(id), unregister(true) + { + + } + + QString presentationId; + QString presentationArgs; + bool unregister; +}; + +Q3DSQmlStreamProxy::renderitem::~renderitem() +{ + delete item; + delete component; +} + +Q3DSQmlStreamProxy::Q3DSQmlStreamProxy(QObject *parent) + : QObject(parent), m_engine(nullptr), m_settings(nullptr) +{ +} + +Q3DSQmlStreamProxy::~Q3DSQmlStreamProxy() +{ + for (Q3DSQmlStreamProducer *p : m_streamProducers) { + IQ3DSQmlStreamService::getQmlStreamService()->unregisterProducer(p); + delete p; + } +} + +void Q3DSQmlStreamProxy::loadPresentationItem(const QString& presentationId, + const QString& presentationArgs) +{ + if (!m_engine) { + m_engine = new QQmlEngine; + + // Add extra import path for binary installations + QString extraImportPath(QStringLiteral("%1/qml")); + m_engine->addImportPath(extraImportPath.arg(QGuiApplication::applicationDirPath())); + + m_engine->setIncubationController(new Q3DSIncubationController(this)); + } + + QString itemPath = presentationArgs; + itemPath.replace("\\", "/"); + + QUrl purl = QUrl(itemPath); + if (purl.isRelative()) { + purl.setPath(m_path.path() + QStringLiteral("/") + purl.path()); + purl.setScheme(m_path.scheme()); + } else { + purl = pathToUrl(itemPath); + } + + QQmlComponent *component = new QQmlComponent(m_engine, purl); + if (!component) + return; + renderitem *item = new renderitem; + item->args = itemPath; + item->component = component; + item->presentationId = presentationId; + m_loadedItems.push_back(item); + + if (component->isLoading()) + connect(component, &QQmlComponent::statusChanged, this, &Q3DSQmlStreamProxy::itemLoaded); + else + itemLoaded(); +} + +void Q3DSQmlStreamProxy::itemLoaded() +{ + for (renderitem *item : m_loadedItems) { + if (item->item == nullptr && item->component->isLoading() == false) { + disconnect(item->component, &QQmlComponent::statusChanged, + this, &Q3DSQmlStreamProxy::itemLoaded); + if (!item->component->errors().isEmpty()) { + QList<QQmlError> errorList = item->component->errors(); + for (const QQmlError &error: errorList) + qWarning() << error.url() << error.line() << error; + m_loadedItems.removeAll(item); + delete item; + } else { + QObject *root = item->component->create(); + if (!root) { + QList<QQmlError> errorList = item->component->errors(); + for (const QQmlError &error: errorList) + qWarning() << error.url() << error.line() << error; + m_loadedItems.removeAll(item); + delete item; + } else { + QQuickItem *qi = qobject_cast<QQuickItem *>(root); + if (!qi) { + m_loadedItems.removeAll(item); + delete item; + } else { + item->item = qi; + m_streamProducers[item->presentationId]->setPresentationItem(qi); + } + } + } + } + } +} + +QUrl Q3DSQmlStreamProxy::pathToUrl(const QString &path) +{ + QUrl retval; + if (path.startsWith(QStringLiteral(":"))) { + retval.setScheme(QStringLiteral("qrc")); + retval.setPath(path.mid(1)); + } else if (path.startsWith(QStringLiteral("qrc:"), Qt::CaseInsensitive)) { + retval.setScheme(QStringLiteral("qrc")); + retval.setPath(path.mid(4)); + } else { + retval.setScheme(QStringLiteral("file")); + retval.setPath(path); + } + return retval; +} + +bool Q3DSQmlStreamProxy::event(QEvent *event) +{ + if (event->type() == QEvent::User) { + Qt3DSQmlStreamEvent *e = static_cast<Qt3DSQmlStreamEvent *>(event); + Q3DSQmlStreamProducer *producer = nullptr; + if (e->unregister && m_streamProducers.contains(e->presentationId)) { + for (int i = 0; i < m_loadedItems.size(); i++) { + if (m_loadedItems[i]->presentationId == e->presentationId) { + delete m_loadedItems[i]; + m_loadedItems.remove(i); + break; + } + } + producer = static_cast<Q3DSQmlStreamProducer *>( + m_streamProducers.take(e->presentationId)); + IQ3DSQmlStreamService::getQmlStreamService()->unregisterProducer(producer); + delete producer; + return true; + } + if (!m_streamProducers.contains(e->presentationId)) { + producer = new Q3DSQmlStreamProducer(e->presentationId, e->presentationArgs, this); + m_streamProducers[e->presentationId] = producer; + IQ3DSQmlStreamService::getQmlStreamService() + ->registerProducer(producer, e->presentationId.toLatin1().data()); + } else { + producer = static_cast<Q3DSQmlStreamProducer *>(m_streamProducers[e->presentationId]); + } + + if (m_settings) { + bool streamFound = false; + for (Q3DSQmlStream *s : m_settings->qmlStreamsList()) { + if (s->presentationId() == e->presentationId) { + producer->setPresentationItem(s->item()); + streamFound = true; + break; + } + } + if (!streamFound && !e->presentationArgs.isNull()) + loadPresentationItem(e->presentationId, e->presentationArgs); + } else if (!e->presentationArgs.isNull()){ + loadPresentationItem(e->presentationId, e->presentationArgs); + } + return true; + } + return false; +} + +void Q3DSQmlStreamProxy::registerPresentation(const QString &presentationId, const QString &args) +{ + QCoreApplication::postEvent(this, + new Qt3DSQmlStreamEvent(QString(presentationId), QString(args))); +} + +void Q3DSQmlStreamProxy::unregisterPresentation(const QString &presentationId) +{ + QCoreApplication::postEvent(this, new Qt3DSQmlStreamEvent(QString(presentationId))); +} + +void Q3DSQmlStreamProxy::setSettings(Q3DSSubPresentationSettings *settings) +{ + m_settings = settings; +} + +void Q3DSQmlStreamProxy::setPath(const QString& path) +{ + QString modPath = QFileInfo(path).path(); // path() strips filename out + m_path = pathToUrl(modPath); +} + +void Q3DSQmlStreamProxy::setEngine(QQmlEngine *engine) +{ + if (m_engine) + delete m_engine; + + m_engine = engine; + + // Add extra import path for binary installations + QString extraImportPath(QStringLiteral("%1/qml")); + m_engine->addImportPath(extraImportPath.arg(QGuiApplication::applicationDirPath())); + + m_engine->setIncubationController(new Q3DSIncubationController(this)); +} diff --git a/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlstreamproxy.h b/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlstreamproxy.h new file mode 100644 index 00000000..85a1cc6d --- /dev/null +++ b/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlstreamproxy.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3DS_QMLSTREAM_PROXY_H +#define Q3DS_QMLSTREAM_PROXY_H + +#include <QtCore/QObject> +#include <QtCore/QEvent> +#include <QtCore/QString> +#include <QtCore/QVector> +#include <QtQml/QQmlEngine> + +#include "q3dsqmlstreamproducer.h" +#include "q3dsqmlsubpresentationsettings.h" + +class Q3DS_QMLSTREAMERSHARED_EXPORT Q3DSQmlStreamProxy : public QObject +{ + Q_OBJECT + +public: + Q3DSQmlStreamProxy(QObject *parent = nullptr); + ~Q3DSQmlStreamProxy(); + + bool event(QEvent *event) Q_DECL_OVERRIDE; + void registerPresentation(const QString &presentationId, const QString &args); + void unregisterPresentation(const QString &presentationId); + void setSettings(Q3DSSubPresentationSettings *settings); + void setPath(const QString& path); + void setEngine(QQmlEngine *engine); + +private: + void loadPresentationItem(const QString& presentationId, const QString& presentationArgs); + void itemLoaded(); + QUrl pathToUrl(const QString &path); + + QQmlEngine *m_engine; + Q3DSSubPresentationSettings *m_settings; + QMap<QString, Q3DSQmlStreamProducer *> m_streamProducers; + struct renderitem { + QString args; + QString presentationId; + QQmlComponent *component; + QQuickItem *item; + renderitem() + : component(nullptr), item(nullptr) {} + ~renderitem(); + }; + + QUrl m_path; + QVector<renderitem *> m_loadedItems; +}; + +#endif // Q3DS_QMLSTREAM_PROXY_H diff --git a/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlstreamrenderer.cpp b/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlstreamrenderer.cpp new file mode 100644 index 00000000..f1879a6e --- /dev/null +++ b/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlstreamrenderer.cpp @@ -0,0 +1,483 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "q3dsqmlstreamrenderer.h" + +#include <QCoreApplication> +#include <qdebug.h> +#include <QOpenGLContext> +#include <QSurface> +#include <QPainter> +#include <QOpenGLFunctions> +#include <QWindow> +#include <QQuickWindow> +#include <QQuickRenderControl> +#include <QtQml/QQmlEngine> +#include <QtQml/QQmlContext> +#include <QQuickWindow> +#include <QQuickItem> +#include <QThread> +#include <QOffscreenSurface> +#include <QOpenGLFramebufferObject> +#include <QOpenGLShaderProgram> +#include <QOpenGLBuffer> +#include <QOpenGLVertexArrayObject> + +Q_GLOBAL_STATIC(QThread, renderThread) +Q_GLOBAL_STATIC(QAtomicInt, renderThreadClientCount) + +#define RenderEvent(name, value) \ + class name : public QEvent \ + { \ + public: \ + name() : QEvent(_type) {} \ + static const QEvent::Type _type; \ + }; \ + const QEvent::Type name::_type = QEvent::Type(value); + +RenderEvent(InitializeRender, QEvent::User + 1) +RenderEvent(RequestUpdate, QEvent::User + 2) +RenderEvent(InitializeRenderThread, QEvent::User + 3) +RenderEvent(PrepareRender, QEvent::User + 4) +RenderEvent(Cleanup, QEvent::User + 5) + +#define EventType(e) (e::_type) + +class RenderControl : public QQuickRenderControl +{ +public: + RenderControl(QWindow *w) + : m_window(w) + { + } + + QWindow *renderWindow(QPoint *offset) Q_DECL_OVERRIDE + { + if (offset) + *offset = QPoint(0, 0); + return m_window; + } + +private: + QWindow *m_window; +}; + +Q3DSQmlStreamEventHandler::Q3DSQmlStreamEventHandler(Q3DSQmlStreamRenderer *renderer) + : m_renderer(renderer) +{ + +} + +bool Q3DSQmlStreamEventHandler::event(QEvent *e) +{ + switch (e->type()) { + + case EventType(RequestUpdate): { + m_renderer->renderTexture(); + return true; + } + + case EventType(InitializeRenderThread): { + m_renderer->initializeRender(); + return true; + } + + case EventType(Cleanup): { + m_renderer->cleanup(); + return true; + } + + default: + break; + } + return QObject::event(e); +} + +Q3DSQmlStreamRenderer::Q3DSQmlStreamRenderer() + : m_renderControl(nullptr) + , m_quickWindow(nullptr) + , m_rootItem(nullptr) + , m_frameBuffer(nullptr) + , m_program(nullptr) + , m_vao(nullptr) + , m_vertices(nullptr) + , m_context(nullptr) + , m_offscreenSurface(nullptr) + , m_renderObject(nullptr) + , m_renderThread(nullptr) + , m_requestUpdate(false) + , m_initialized(false) + , m_prepared(false) + , m_update(false) + , m_delayedUpdateRequest(false) +{ + renderThreadClientCount->fetchAndAddAcquire(1); + + QSurfaceFormat format = QSurfaceFormat::defaultFormat(); + if (QOpenGLContext::currentContext()) + format = QOpenGLContext::currentContext()->format(); + else { + format.setDepthBufferSize(24); + format.setStencilBufferSize(8); + } + + m_offscreenSurface = new QOffscreenSurface; + m_offscreenSurface->setFormat(format); + m_offscreenSurface->create(); + + m_renderControl = new RenderControl(nullptr); + + connect(m_renderControl, &QQuickRenderControl::renderRequested, + this, &Q3DSQmlStreamRenderer::requestUpdate); + connect(m_renderControl, &QQuickRenderControl::sceneChanged, + this, &Q3DSQmlStreamRenderer::requestUpdate); + + m_quickWindow = new QQuickWindow(m_renderControl); + m_quickWindow->setClearBeforeRendering(true); + m_quickWindow->setColor(Qt::transparent); + + m_renderObject = new Q3DSQmlStreamEventHandler(this); + renderThread->setObjectName(QStringLiteral("Qt3DSQmlStreamRenderer::renderThread")); + m_renderThread = renderThread; + + m_renderObject->moveToThread(m_renderThread); + if (!m_renderThread->isRunning()) + m_renderThread->start(); +} + +Q3DSQmlStreamRenderer::~Q3DSQmlStreamRenderer() +{ + QMutexLocker lock(&m_mutex); + QCoreApplication::postEvent(m_renderObject, new Cleanup()); + m_waitCondition.wait(&m_mutex); + + delete m_offscreenSurface; + delete m_renderControl; + delete m_quickWindow; + delete m_renderObject; + + renderThreadClientCount->fetchAndSubAcquire(1); + if (renderThreadClientCount->load() == 0) + renderThread->quit(); +} + +void Q3DSQmlStreamRenderer::cleanup() +{ + if (m_context) + m_context->makeCurrent(m_offscreenSurface); + if (m_renderControl) + m_renderControl->invalidate(); + + delete m_frameBuffer; + delete m_program; + delete m_vertices; + + if (m_context) + m_context->doneCurrent(); + delete m_context; + + if (m_renderObject) + m_renderObject->moveToThread(QCoreApplication::instance()->thread()); + m_waitCondition.wakeOne(); +} + +bool Q3DSQmlStreamRenderer::initialize(QOpenGLContext *context, QSurface *surface) +{ + Q_UNUSED(surface); + QMutexLocker lock(&m_renderMutex); + if (!m_context) { + m_context = new QOpenGLContext(); + m_context->setShareContext(context); + m_context->setFormat(context->format()); + m_context->create(); + m_context->moveToThread(m_renderThread); + } + + if (!m_rootItem) { + return true; + } + + if (m_initialized) { + Q_ASSERT(QOpenGLContext::areSharing(context, m_context)); + return true; + } + + m_rootItem->setParentItem(m_quickWindow->contentItem()); + + updateSizes(); + + m_initialized = true; + // Initialize render thread + QCoreApplication::postEvent(m_renderObject, + new InitializeRenderThread()); + return true; +} +void Q3DSQmlStreamRenderer::initializeFboCopy() +{ + m_program = new QOpenGLShaderProgram; + if (m_context->format().renderableType() == QSurfaceFormat::OpenGLES) { + static const char *vsSource = + "attribute highp vec4 pos;\n" + "attribute highp vec2 tc;\n" + "varying lowp vec2 texcoord;\n" + "void main() {\n" + " texcoord = tc;\n" + " gl_Position = pos;\n" + "}\n"; + static const char *fsSource = + "varying highp vec2 texcoord;\n" + "uniform sampler2D sampler;\n" + "void main() {\n" + " gl_FragColor = texture2D(sampler, texcoord);\n" + "}\n"; + m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vsSource); + m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fsSource); + } else { + static const char *vsSource = + "#version 150 core\n" + "in vec4 pos;\n" + "in vec2 tc;\n" + "out vec2 texcoord;\n" + "void main() {\n" + " texcoord = tc;\n" + " gl_Position = pos;\n" + "}\n"; + static const char *fsSource = + "#version 150 core\n" + "in vec2 texcoord;\n" + "out vec4 fragColor;\n" + "uniform sampler2D sampler;\n" + "void main() {\n" + " fragColor = texture(sampler, texcoord);\n" + "}\n"; + m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vsSource); + m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fsSource); + } + + m_program->bindAttributeLocation("pos", 0); + m_program->bindAttributeLocation("tc", 1); + + if (!m_program->link()) { + QByteArray logData(m_program->log().toLocal8Bit()); + const char *log = logData.data(); + qFatal("Failed to create shader program: %s", log); + } + + m_vertices = new QOpenGLBuffer; + m_vertices->create(); + m_vertices->bind(); + + static const float vertices[] = + { + -1, -1, 0, 1, 0, 0, + 1, -1, 0, 1, 1, 0, + 1, 1, 0, 1, 1, 1, + -1, -1, 0, 1, 0, 0, + 1, 1, 0, 1, 1, 1, + -1, 1, 0, 1, 0, 1, + }; + + m_vertices->allocate(vertices, sizeof(vertices)); + m_vertices->release(); +} + +void Q3DSQmlStreamRenderer::initializeRender() +{ + QMutexLocker lock(&m_renderMutex); + m_context->makeCurrent(m_offscreenSurface); + m_renderControl->initialize(m_context); + m_context->doneCurrent(); + QCoreApplication::postEvent(this, new PrepareRender()); +} + +QSize Q3DSQmlStreamRenderer::getDesiredSize() +{ + return m_size; +} + +E_TEXTURE_FORMAT Q3DSQmlStreamRenderer::getDesiredFormat() +{ + return E_TEXTURE_RGBA8; +} + +bool Q3DSQmlStreamRenderer::isUpdateRequested() +{ + return m_update; +} + +// Called by stream renderer client when it stops using the renderer +// TODO: We are sharing the context so stop using it. +void Q3DSQmlStreamRenderer::uninitialize() +{ +} + +void Q3DSQmlStreamRenderer::setItem(QQuickItem *item) +{ + if (item && m_rootItem && m_initialized) { + QMutexLocker lock(&m_renderMutex); + m_rootItem->setParentItem(nullptr); + m_rootItem = item; + m_rootItem->setParentItem(m_quickWindow->contentItem()); + updateSizes(); + } else { + if (item && m_rootItem != item) { + m_rootItem = item; + + if (m_context) + initialize(m_context, nullptr); + } + } +} + +bool Q3DSQmlStreamRenderer::event(QEvent *event) +{ + switch (event->type()) { + + case EventType(PrepareRender): { + + m_renderControl->prepareThread(m_renderThread); + m_prepared = true; + + if (m_delayedUpdateRequest) { + QCoreApplication::postEvent(this, new RequestUpdate()); + m_delayedUpdateRequest = false; + } + + return true; + } + + case EventType(RequestUpdate): { + + m_renderControl->polishItems(); + QMutexLocker lock(&m_mutex); + QCoreApplication::postEvent(m_renderObject, new RequestUpdate()); + m_waitCondition.wait(&m_mutex); + return true; + } + + default: + break; + } + + return QObject::event(event); +} + +void Q3DSQmlStreamRenderer::updateSizes() +{ + if (m_rootItem->width() > 0 && m_rootItem->height() > 0) { + m_size = QSize(m_rootItem->width(), m_rootItem->height()); + } else { + m_rootItem->setWidth(256); + m_rootItem->setHeight(256); + } + + m_quickWindow->setGeometry(0, 0, m_size.width(), m_size.height()); +} + +void Q3DSQmlStreamRenderer::requestUpdate() +{ + if (!m_requestUpdate) { + m_requestUpdate = true; + if (m_initialized) + QCoreApplication::postEvent(this, new RequestUpdate()); + else + m_delayedUpdateRequest = true; + } +} + +void Q3DSQmlStreamRenderer::renderTexture() +{ + QMutexLocker lock(&m_renderMutex); + m_context->makeCurrent(m_offscreenSurface); + + if (!m_frameBuffer || m_frameBuffer->size() != m_size) { + if (m_frameBuffer) + delete m_frameBuffer; + + m_frameBuffer = new QOpenGLFramebufferObject(m_size); + m_frameBuffer->setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); + m_quickWindow->setRenderTarget(m_frameBuffer); + } + + { + QMutexLocker lock(&m_mutex); + if (m_requestUpdate) { + m_requestUpdate = false; + m_renderControl->sync(); + m_renderControl->render(); + m_waitCondition.wakeOne(); + } + } + + m_context->functions()->glFlush(); + m_quickWindow->resetOpenGLState(); + m_context->doneCurrent(); + m_update = true; +} + +void Q3DSQmlStreamRenderer::render() +{ + QMutexLocker lock(&m_renderMutex); + if (m_update && m_initialized) { + QOpenGLContext *context = QOpenGLContext::currentContext(); + QOpenGLFunctions *func = context->functions(); + GLuint texture = m_frameBuffer->texture(); + func->glDisable(GL_DEPTH_TEST); + func->glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + + if (!m_program) + initializeFboCopy(); + + m_program->bind(); + + if (!m_vao) { + m_vao = new QOpenGLVertexArrayObject; + m_vao->create(); + m_vao->bind(); + m_vertices->bind(); + + m_program->enableAttributeArray(0); + m_program->enableAttributeArray(1); + func->glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 6 * sizeof(float), 0); + func->glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 6 * sizeof(float), + (const void *)(4 * sizeof(GLfloat))); + m_vertices->release(); + } else { + m_vao->bind(); + } + + func->glActiveTexture(GL_TEXTURE0); + func->glBindTexture(GL_TEXTURE_2D, texture); + func->glDrawArrays(GL_TRIANGLES, 0, 6); + func->glEnable(GL_DEPTH_TEST); + + m_program->release(); + m_vao->release(); + } +} diff --git a/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlstreamrenderer.h b/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlstreamrenderer.h new file mode 100644 index 00000000..e9274794 --- /dev/null +++ b/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlstreamrenderer.h @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3DS_QMLSTREAM_RENDERER_H +#define Q3DS_QMLSTREAM_RENDERER_H + +#include "q3dsqmlstreamservice.h" + +#include <QOpenGLFunctions> +#include <QSize> +#include <QThread> +#include <QWaitCondition> +#include <QMutex> + +QT_BEGIN_NAMESPACE +class QQuickRenderControl; +class QQuickWindow; +class QQuickItem; +class QOpenGLContext; +class QOffscreenSurface; +class QOpenGLFramebufferObject; +class QOpenGLShaderProgram; +class QOpenGLBuffer; +class QOpenGLVertexArrayObject; +QT_END_NAMESPACE + +class Q3DSQmlStreamRenderer; + +class Q3DSQmlStreamEventHandler : public QObject +{ + Q_OBJECT +public: + Q3DSQmlStreamEventHandler(Q3DSQmlStreamRenderer *renderer); + bool event(QEvent *e) Q_DECL_OVERRIDE; + +private: + Q3DSQmlStreamRenderer *m_renderer; +}; + +class Q3DSQmlStreamRenderer : public QObject, + public IQ3DSQmlStreamRenderer +{ + Q_OBJECT +public: + Q3DSQmlStreamRenderer(); + virtual ~Q3DSQmlStreamRenderer(); + + bool initialize(QOpenGLContext *context, QSurface *surface) override; + + QSize getDesiredSize() override; + E_TEXTURE_FORMAT getDesiredFormat() override; + bool isUpdateRequested() override; + + void render() override; + + void uninitialize() override; + + void setItem(QQuickItem *item); + + bool event(QEvent *event) Q_DECL_OVERRIDE; + +private: + + void updateSizes(); + void requestUpdate(); + void cleanup(); + void initializeRender(); + void renderTexture(); + void initializeFboCopy(); + + QSize m_size; + QMutex m_mutex, m_renderMutex; + QWaitCondition m_waitCondition; + + QQuickRenderControl *m_renderControl; + QQuickWindow *m_quickWindow; + QQuickItem *m_rootItem; + + QOpenGLFramebufferObject *m_frameBuffer; + QOpenGLShaderProgram *m_program; + QOpenGLVertexArrayObject *m_vao; + QOpenGLBuffer *m_vertices; + QOpenGLContext *m_context; + QOffscreenSurface *m_offscreenSurface; + + Q3DSQmlStreamEventHandler *m_renderObject; + QThread *m_renderThread; + + bool m_requestUpdate; + bool m_initialized; + bool m_prepared; + bool m_update; + bool m_delayedUpdateRequest; + + friend class Q3DSQmlStreamEventHandler; +}; + +#endif // Q3DS_QMLSTREAM_RENDERER_H diff --git a/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlstreamservice.h b/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlstreamservice.h new file mode 100644 index 00000000..2b44fe3b --- /dev/null +++ b/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlstreamservice.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3DS_QMLSTREAM_SERVICE_H +#define Q3DS_QMLSTREAM_SERVICE_H + +#include <qglobal.h> +#include <q3dsqmlstreamer_global.h> + +QT_BEGIN_NAMESPACE +class QOpenGLContext; +class QSurface; +class QSize; +QT_END_NAMESPACE + +enum E_TEXTURE_FORMAT +{ + E_TEXTURE_RGBA8, + E_TEXTURE_UNKNOWN +}; + +class Q3DS_QMLSTREAMERSHARED_EXPORT IQ3DSQmlStreamRenderer +{ +public: + virtual bool initialize(QT_PREPEND_NAMESPACE(QOpenGLContext) *context, QSurface *surface) = 0; + + virtual QSize getDesiredSize() = 0; + virtual E_TEXTURE_FORMAT getDesiredFormat() = 0; + virtual bool isUpdateRequested() = 0; + + virtual void render() = 0; + + virtual void uninitialize() = 0; +}; + +class Q3DS_QMLSTREAMERSHARED_EXPORT IQ3DSQmlStreamProducer +{ +public: + virtual IQ3DSQmlStreamRenderer *getRenderer() = 0; +}; + +class Q3DS_QMLSTREAMERSHARED_EXPORT IQ3DSQmlStreamService +{ +public: + virtual IQ3DSQmlStreamRenderer *getRenderer(const char *id) = 0; + virtual bool registerProducer(IQ3DSQmlStreamProducer *producer, const char *id) = 0; + virtual void unregisterProducer(IQ3DSQmlStreamProducer *producer) = 0; + + static IQ3DSQmlStreamService *getQmlStreamService(); +}; + +#endif // Q3DS_QMLSTREAM_SERVICE_H + + diff --git a/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlsubpresentationsettings.cpp b/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlsubpresentationsettings.cpp new file mode 100644 index 00000000..bde5ad31 --- /dev/null +++ b/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlsubpresentationsettings.cpp @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "q3dsqmlsubpresentationsettings.h" +#include "q3dsqmlstream.h" + +/*! + \qmltype SubPresentationSettings + \instantiates Q3DSSubPresentationSettings + \inqmlmodule Qt3DStudio + \ingroup OpenGLRuntime + \brief + + \sa Studio3D, Presentation, QmlStream +*/ +/*! + \class Q3DSSubPresentationSettings + \inmodule OpenGLRuntime + \since Qt 3D Studio 2.0 + \brief Settings for subpresentations. + \param parent + + \sa Q3DSPresentation, Q3DSQmlStream + */ +Q3DSSubPresentationSettings::Q3DSSubPresentationSettings(QObject *parent) + : QObject(parent) +{ +} + +Q3DSSubPresentationSettings::~Q3DSSubPresentationSettings() +{ + qDeleteAll(m_list); +} + +/*! + * \qmlproperty variant SubPresentationSettings::qmlStream + * Contains the QML streams to be used as subpresentations. + */ +/*! + * \property Q3DSSubPresentationSettings::qmlStreams + * Contains the QML streams to be used as subpresentations. + */ +QQmlListProperty<Q3DSQmlStream> Q3DSSubPresentationSettings::qmlStreams() +{ + return QQmlListProperty<Q3DSQmlStream>(this, m_list); +} + +QList<Q3DSQmlStream *> Q3DSSubPresentationSettings::qmlStreamsList() +{ + return m_list; +} + diff --git a/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlsubpresentationsettings.h b/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlsubpresentationsettings.h new file mode 100644 index 00000000..b295f2a0 --- /dev/null +++ b/src/Runtime/ogl-runtime/src/qmlstreamer/q3dsqmlsubpresentationsettings.h @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3DS_QML_SUBPRESENTATION_SETTINGS_H +#define Q3DS_QML_SUBPRESENTATION_SETTINGS_H + +#include <QtCore/QObject> +#include <QtCore/QList> +#include <QtQml/QQmlListProperty> + +#include "q3dsqmlstream.h" +#include "q3dsqmlstreamer_global.h" + +class Q3DS_QMLSTREAMERSHARED_EXPORT Q3DSSubPresentationSettings : public QObject +{ + Q_OBJECT + Q_PROPERTY(QQmlListProperty<Q3DSQmlStream> qmlStreams READ qmlStreams) +public: + + Q3DSSubPresentationSettings(QObject *parent = nullptr); + ~Q3DSSubPresentationSettings(); + + QQmlListProperty<Q3DSQmlStream> qmlStreams(); + QList<Q3DSQmlStream *> qmlStreamsList(); +private: + QList<Q3DSQmlStream *> m_list; +}; + +#endif // Q3DS_QML_SUBPRESENTATION_SETTINGS_H diff --git a/src/Runtime/ogl-runtime/src/qmlstreamer/qmlstreamer.pro b/src/Runtime/ogl-runtime/src/qmlstreamer/qmlstreamer.pro new file mode 100644 index 00000000..5e82c7c0 --- /dev/null +++ b/src/Runtime/ogl-runtime/src/qmlstreamer/qmlstreamer.pro @@ -0,0 +1,50 @@ +TEMPLATE = lib +TARGET = qt3dsqmlstreamer +VERSION = $$MODULE_VERSION +include($$PWD/../../commonplatform.pri) + +CONFIG += installed +load(qt_helper_lib) + +# qt_helper_lib assumes non-qt lib, so it clears some qt variables, reset those +CONFIG += qt +QT += core qml quick opengl + +DEFINES += QMLSTREAMER_LIBRARY + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which as been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += \ + q3dsqmlstream.cpp \ + q3dsqmlstreamerserviceimpl.cpp \ + q3dsqmlstreamproducer.cpp \ + q3dsqmlstreamproxy.cpp \ + q3dsqmlstreamrenderer.cpp \ + q3dsqmlsubpresentationsettings.cpp + +HEADERS += \ + q3dsincubationcontroller.h \ + q3dsqmlstream.h \ + q3dsqmlstreamer_global.h \ + q3dsqmlstreamerserviceimpl.h \ + q3dsqmlstreamproducer.h \ + q3dsqmlstreamproxy.h \ + q3dsqmlstreamrenderer.h \ + q3dsqmlstreamservice.h \ + q3dsqmlsubpresentationsettings.h + +INCLUDEPATH += \ + $$PWD/../Runtime/ogl-runtime/src/engine \ + $$PWD/../Runtime/ogl-runtime/src/system \ + $$PWD/../QtExtras/qmlstreamer + +macos:QMAKE_LFLAGS_SONAME = -Wl,-install_name,@rpath/ |