From 5876bccf26918fb25b711b5173f8a71ae2f15084 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 13 Dec 2018 14:31:35 +0100 Subject: [PATCH] mw: work around weird issues in shadow builds on mac --- .../multiwindow_threaded.cpp | 115 +-------------- .../multiwindow_threaded.pro | 6 +- examples/rhi/multiwindow_threaded/window.cpp | 135 ++++++++++++++++++ examples/rhi/multiwindow_threaded/window.h | 86 +++++++++++ 4 files changed, 229 insertions(+), 113 deletions(-) create mode 100644 examples/rhi/multiwindow_threaded/window.cpp create mode 100644 examples/rhi/multiwindow_threaded/window.h diff --git a/examples/rhi/multiwindow_threaded/multiwindow_threaded.cpp b/examples/rhi/multiwindow_threaded/multiwindow_threaded.cpp index 2ac79cf..af6385c 100644 --- a/examples/rhi/multiwindow_threaded/multiwindow_threaded.cpp +++ b/examples/rhi/multiwindow_threaded/multiwindow_threaded.cpp @@ -61,8 +61,6 @@ #include #include #include -#include -#include #include #include @@ -87,6 +85,8 @@ #include #endif +#include "window.h" + #include "../shared/cube.h" static QBakedShader getShader(const QString &name) @@ -98,14 +98,6 @@ static QBakedShader getShader(const QString &name) return QBakedShader(); } -enum GraphicsApi -{ - OpenGL, - Vulkan, - D3D11, - Metal -}; - static GraphicsApi graphicsApi; static QString graphicsApiName() @@ -663,105 +655,6 @@ void Renderer::sendSyncSurfaceSize() thread->mutex.unlock(); } -class Window : public QWindow -{ - Q_OBJECT - -public: - Window(const QString &title); - ~Window(); - - void exposeEvent(QExposeEvent *) override; - bool event(QEvent *) override; - -signals: - void initRequested(); - void renderRequested(bool newlyExposed); - void surfaceGoingAway(); - void syncSurfaceSizeRequested(); - -protected: - bool m_running = false; - bool m_notExposed = true; -}; - -Window::Window(const QString &title) -{ - switch (graphicsApi) { - case OpenGL: - setSurfaceType(OpenGLSurface); - break; - case Vulkan: - setSurfaceType(VulkanSurface); - setVulkanInstance(instance); - break; - case D3D11: - setSurfaceType(OpenGLSurface); // not a typo - break; - case Metal: -#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)) - setSurfaceType(MetalSurface); -#endif - break; - default: - break; - } - - resize(800, 600); - setTitle(title); -} - -Window::~Window() -{ -} - -void Window::exposeEvent(QExposeEvent *) -{ - if (isExposed()) { - if (!m_running) { - // initialize and start rendering when the window becomes usable for graphics purposes - m_running = true; - m_notExposed = false; - emit initRequested(); - emit renderRequested(true); - } else { - // continue when exposed again - if (m_notExposed) { - m_notExposed = false; - emit renderRequested(true); - } else { - // resize generates exposes - this is very important here (unlike in a single-threaded renderer) - emit syncSurfaceSizeRequested(); - } - } - } else { - // stop pushing frames when not exposed (on some platforms this is essential, optional on others) - if (m_running) - m_notExposed = true; - } -} - -bool Window::event(QEvent *e) -{ - switch (e->type()) { - case QEvent::UpdateRequest: - if (!m_notExposed) - emit renderRequested(false); - break; - - case QEvent::PlatformSurface: - // this is the proper time to tear down the swapchain (while the native window and surface are still around) - if (static_cast(e)->surfaceEventType() == QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed) - emit surfaceGoingAway(); - break; - - default: - break; - } - - return QWindow::event(e); -} - struct WindowAndRenderer { QWindow *window; @@ -774,7 +667,7 @@ void createWindow() { static QColor colors[] = { Qt::red, Qt::green, Qt::blue, Qt::yellow, Qt::cyan, Qt::gray }; const int n = windows.count(); - Window *w = new Window(QString::asprintf("Window+Thread #%d (%s)", n, qPrintable(graphicsApiName()))); + Window *w = new Window(QString::asprintf("Window+Thread #%d (%s)", n, qPrintable(graphicsApiName())), graphicsApi); Renderer *renderer = new Renderer(w, colors[n % 6], n % 3);; QObject::connect(w, &Window::initRequested, w, [renderer] { renderer->sendInit(); @@ -912,5 +805,3 @@ int main(int argc, char **argv) return result; } - -#include "multiwindow_threaded.moc" diff --git a/examples/rhi/multiwindow_threaded/multiwindow_threaded.pro b/examples/rhi/multiwindow_threaded/multiwindow_threaded.pro index a72e94f..5c780a7 100644 --- a/examples/rhi/multiwindow_threaded/multiwindow_threaded.pro +++ b/examples/rhi/multiwindow_threaded/multiwindow_threaded.pro @@ -3,7 +3,11 @@ TEMPLATE = app QT += shadertools rhi widgets SOURCES = \ - multiwindow_threaded.cpp + multiwindow_threaded.cpp \ + window.cpp + +HEADERS = \ + window.h RESOURCES = multiwindow_threaded.qrc diff --git a/examples/rhi/multiwindow_threaded/window.cpp b/examples/rhi/multiwindow_threaded/window.cpp new file mode 100644 index 0000000..2b17a2c --- /dev/null +++ b/examples/rhi/multiwindow_threaded/window.cpp @@ -0,0 +1,135 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "window.h" +#include + +#if QT_CONFIG(vulkan) +extern QVulkanInstance *instance; +#endif + +Window::Window(const QString &title, GraphicsApi api) +{ + switch (api) { + case OpenGL: + setSurfaceType(OpenGLSurface); + break; +#if QT_CONFIG(vulkan) + case Vulkan: + setSurfaceType(VulkanSurface); + setVulkanInstance(instance); + break; +#endif + case D3D11: + setSurfaceType(OpenGLSurface); // not a typo + break; + case Metal: +#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)) + setSurfaceType(MetalSurface); +#endif + break; + default: + break; + } + + resize(800, 600); + setTitle(title); +} + +Window::~Window() +{ +} + +void Window::exposeEvent(QExposeEvent *) +{ + if (isExposed()) { + if (!m_running) { + // initialize and start rendering when the window becomes usable for graphics purposes + m_running = true; + m_notExposed = false; + emit initRequested(); + emit renderRequested(true); + } else { + // continue when exposed again + if (m_notExposed) { + m_notExposed = false; + emit renderRequested(true); + } else { + // resize generates exposes - this is very important here (unlike in a single-threaded renderer) + emit syncSurfaceSizeRequested(); + } + } + } else { + // stop pushing frames when not exposed (on some platforms this is essential, optional on others) + if (m_running) + m_notExposed = true; + } +} + +bool Window::event(QEvent *e) +{ + switch (e->type()) { + case QEvent::UpdateRequest: + if (!m_notExposed) + emit renderRequested(false); + break; + + case QEvent::PlatformSurface: + // this is the proper time to tear down the swapchain (while the native window and surface are still around) + if (static_cast(e)->surfaceEventType() == QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed) + emit surfaceGoingAway(); + break; + + default: + break; + } + + return QWindow::event(e); +} diff --git a/examples/rhi/multiwindow_threaded/window.h b/examples/rhi/multiwindow_threaded/window.h new file mode 100644 index 0000000..7810858 --- /dev/null +++ b/examples/rhi/multiwindow_threaded/window.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include + +enum GraphicsApi +{ + OpenGL, + Vulkan, + D3D11, + Metal +}; + +class Window : public QWindow +{ + Q_OBJECT + +public: + Window(const QString &title, GraphicsApi api); + ~Window(); + + void exposeEvent(QExposeEvent *) override; + bool event(QEvent *) override; + +signals: + void initRequested(); + void renderRequested(bool newlyExposed); + void surfaceGoingAway(); + void syncSurfaceSizeRequested(); + +protected: + bool m_running = false; + bool m_notExposed = true; +}; + +#endif -- GitLab