diff options
Diffstat (limited to 'src/render')
-rw-r--r-- | src/render/frontend/qrenderaspect.cpp | 73 | ||||
-rw-r--r-- | src/render/frontend/qrenderaspect_p.h | 2 |
2 files changed, 72 insertions, 3 deletions
diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp index 72f114481..bc79982ba 100644 --- a/src/render/frontend/qrenderaspect.cpp +++ b/src/render/frontend/qrenderaspect.cpp @@ -170,13 +170,53 @@ #include <Qt3DCore/QAspectEngine> #include <Qt3DCore/private/qservicelocator_p.h> -#include <QDebug> -#include <QOffscreenSurface> #include <QThread> -#include <QWindow> + +#ifdef Q_OS_MACOS +#include <mach-o/dyld.h> +#include <dlfcn.h> +#endif QT_BEGIN_NAMESPACE +#ifdef Q_OS_MACOS +namespace { + +// adapted from qcocoahelpers.mm in QtBase +typedef QPair<QOperatingSystemVersion, QOperatingSystemVersion> VersionTuple; + +VersionTuple versionsForImage(const mach_header *machHeader) +{ + static auto makeVersionTuple = [](uint32_t dt, uint32_t sdk) { + return qMakePair( + QOperatingSystemVersion(QOperatingSystemVersion::MacOS, + dt >> 16 & 0xffff, dt >> 8 & 0xff, dt & 0xff), + QOperatingSystemVersion(QOperatingSystemVersion::MacOS, + sdk >> 16 & 0xffff, sdk >> 8 & 0xff, sdk & 0xff) + ); + }; + + auto commandCursor = uintptr_t(machHeader) + sizeof(mach_header_64); + for (uint32_t i = 0; i < machHeader->ncmds; ++i) { + load_command *loadCommand = reinterpret_cast<load_command *>(commandCursor); + if (loadCommand->cmd == LC_VERSION_MIN_MACOSX) { + auto versionCommand = reinterpret_cast<version_min_command *>(loadCommand); + return makeVersionTuple(versionCommand->version, versionCommand->sdk); +#if QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_13) + } else if (loadCommand->cmd == LC_BUILD_VERSION) { + auto versionCommand = reinterpret_cast<build_version_command *>(loadCommand); + return makeVersionTuple(versionCommand->minos, versionCommand->sdk); +#endif + } + commandCursor += loadCommand->cmdsize; + } + Q_ASSERT_X(false, "QCocoaIntegration", "Could not find any version load command"); + Q_UNREACHABLE(); +} + +} +#endif + using namespace Qt3DCore; namespace Qt3DRender { @@ -202,11 +242,30 @@ QRenderAspectPrivate::QRenderAspectPrivate(QRenderAspect::RenderType type) , m_nodeManagers(nullptr) , m_renderer(nullptr) , m_initialized(false) + , m_renderAfterJobs(false) , m_renderType(type) , m_offscreenHelper(nullptr) { m_instances.append(this); loadSceneParsers(); +#ifdef Q_OS_MACOS + static VersionTuple version = []() { + const mach_header *executableHeader = nullptr; + for (uint32_t i = 0; i < _dyld_image_count(); ++i) { + auto header = _dyld_get_image_header(i); + if (header->filetype == MH_EXECUTE) { + executableHeader = header; + break; + } + } + Q_ASSERT_X(executableHeader, "QCocoaIntegration", "Failed to resolve Mach-O header of executable"); + return versionsForImage(executableHeader); + }(); + if (m_renderType == QRenderAspect::Threaded && version.second >= QOperatingSystemVersion(QOperatingSystemVersion::MacOSMojave)) { + m_renderType = QRenderAspect::Synchronous; + m_renderAfterJobs = true; + } +#endif } /*! \internal */ @@ -239,6 +298,12 @@ void QRenderAspectPrivate::syncDirtyFrontEndNode(QNode *node, QBackendNode *back renderBackend->syncFromFrontEnd(node, firstTime); } +void QRenderAspectPrivate::jobsDone() +{ + if (m_renderAfterJobs) + m_renderer->doRender(true); +} + /*! \internal */ void QRenderAspectPrivate::registerBackendTypes() { @@ -539,6 +604,8 @@ QVariant QRenderAspect::executeCommand(const QStringList &args) void QRenderAspect::onEngineStartup() { Q_D(QRenderAspect); + if (d->m_renderAfterJobs) // synchronous rendering but using QWindow + d->m_renderer->initialize(); Render::NodeManagers *managers = d->m_renderer->nodeManagers(); Render::Entity *rootEntity = managers->lookupResource<Render::Entity, Render::EntityManager>(rootEntityId()); Q_ASSERT(rootEntity); diff --git a/src/render/frontend/qrenderaspect_p.h b/src/render/frontend/qrenderaspect_p.h index b4cb0812c..305e58403 100644 --- a/src/render/frontend/qrenderaspect_p.h +++ b/src/render/frontend/qrenderaspect_p.h @@ -87,6 +87,7 @@ public: static QRenderAspectPrivate* findPrivate(Qt3DCore::QAspectEngine *engine); void syncDirtyFrontEndNode(Qt3DCore::QNode *node, Qt3DCore::QBackendNode *backend, bool firstTime) const override; + void jobsDone() override; void registerBackendTypes(); void unregisterBackendTypes(); @@ -101,6 +102,7 @@ public: Render::AbstractRenderer *m_renderer; bool m_initialized; + bool m_renderAfterJobs; QList<QSceneImporter *> m_sceneImporter; QVector<QString> m_loadedPlugins; QVector<Render::QRenderPlugin *> m_renderPlugins; |