Skip to content

Commit

Permalink
Merge branch 'mjcarroll/qt5qt6' into mjcarroll/qt6
Browse files Browse the repository at this point in the history
Signed-off-by: Michael Carroll <[email protected]>
  • Loading branch information
mjcarroll committed Nov 28, 2023
2 parents aefb832 + dffd3a0 commit a5ed392
Show file tree
Hide file tree
Showing 10 changed files with 202 additions and 139 deletions.
25 changes: 12 additions & 13 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -73,28 +73,27 @@ set(GZ_RENDERING_VER ${gz-rendering9_VERSION_MAJOR})
gz_find_package(gz-msgs11 REQUIRED)
set(GZ_MSGS_VER ${gz-msgs11_VERSION_MAJOR})

# Find if command is available. This is used to enable tests.
# Note that CLI files are installed regardless of whether the dependency is
# available during build time
find_program(HAVE_GZ_TOOLS gz)
set(GZ_TOOLS_VER 2)

#--------------------------------------
# Find QT
gz_find_package (Qt6
set(QT_MAJOR_VERSION 6)
set(QT_MINOR_VERSION 0)
gz_find_package (Qt${QT_MAJOR_VERSION}
VERSION ${QT_MAJOR_VERSION}.${QT_MINOR_VERSION}
COMPONENTS
Core
Quick
QuickControls2
Widgets
Test
REQUIRED
PKGCONFIG "Qt6Core Qt6Quick Qt6QuickControls2 Qt6Widgets"
)

if (BUILD_TESTING)
# Find if command is available. This is used to enable tests.
# Note that CLI files are installed regardless of whether the dependency is
# available during build time
find_program(HAVE_GZ_TOOLS gz)
set(GZ_TOOLS_VER 2)

find_package(Qt6 REQUIRED COMPONENTS Test)
endif()
PKGCONFIG "Qt${QT_MAJOR_VERSION}Core Qt${QT_MAJOR_VERSION}Quick Qt${QT_MAJOR_VERSION}QuickControls2 Qt${QT_MAJOR_VERSION}Widgets")
add_compile_definitions(QT_DISABLE_DEPRECATED_UP_TO=0x050F00)

if(POLICY CMP0100)
cmake_policy(SET CMP0100 NEW)
Expand Down
10 changes: 10 additions & 0 deletions src/Application.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*
*/

#include <qsgrendererinterface.h>
#include <tinyxml2.h>
#include <queue>

Expand Down Expand Up @@ -126,7 +127,12 @@ Application::Application(int &_argc, char **_argv, const WindowType _type,
{
// Use the Metal graphics API on macOS.
gzdbg << "Qt using Metal graphics interface" << std::endl;
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QQuickWindow::setGraphicsApi(QSGRendererInterface::MetalRhi);
#else
QQuickWindow::setSceneGraphBackend(QSGRendererInterface::MetalRhi);
#endif

}

// TODO(srmainwaring): implement facility for overriding the default
Expand Down Expand Up @@ -159,7 +165,11 @@ Application::Application(int &_argc, char **_argv, const WindowType _type,
# endif
);

#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QQuickWindow::setGraphicsApi(QSGRendererInterface::VulkanRhi);
#else
QQuickWindow::setSceneGraphBackend(QSGRendererInterface::VulkanRhi);
#endif
gzdbg << "Qt using Vulkan graphics interface" << std::endl;
}
else
Expand Down
2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ gz_build_tests(TYPE UNIT
TINYXML2::TINYXML2
TEST_LIST
gtest_targets
ENVIRONMENT
ENVIRONMENT
GZ_GUI_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
)

Expand Down
21 changes: 15 additions & 6 deletions src/Conversions_TEST.cc
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,11 @@ TEST(ConversionsTest, MouseEvent)
{
// Press + Shift
{
QMouseEvent qtEvent(QEvent::MouseButtonPress, QPointF(10, 20),
Qt::RightButton, Qt::MiddleButton, Qt::ShiftModifier);
QMouseEvent qtEvent(QEvent::MouseButtonPress,
QPointF(10, 20), QPointF(10, 20),
Qt::RightButton,
Qt::MiddleButton,
Qt::ShiftModifier);

auto gzEvent = convert(qtEvent);

Expand All @@ -119,8 +122,11 @@ TEST(ConversionsTest, MouseEvent)

// Release + Control
{
QMouseEvent qtEvent(QEvent::MouseButtonRelease, QPointF(0, 200),
Qt::MiddleButton, Qt::RightButton, Qt::ControlModifier);
QMouseEvent qtEvent(QEvent::MouseButtonRelease,
QPointF(0, 200), QPointF(0, 200),
Qt::MiddleButton,
Qt::RightButton,
Qt::ControlModifier);

auto gzEvent = convert(qtEvent);

Expand All @@ -134,8 +140,11 @@ TEST(ConversionsTest, MouseEvent)

// Move + Alt
{
QMouseEvent qtEvent(QEvent::MouseMove, QPointF(123, 456),
Qt::LeftButton, Qt::LeftButton, Qt::AltModifier);
QMouseEvent qtEvent(QEvent::MouseMove,
QPointF(123, 456), QPointF(123, 456),
Qt::LeftButton,
Qt::LeftButton,
Qt::AltModifier);

auto gzEvent = convert(qtEvent);

Expand Down
35 changes: 26 additions & 9 deletions src/plugins/minimal_scene/MinimalScene.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <map>
#include <sstream>
#include <string>
#include <utility>
#include <vector>

#include <gz/common/Console.hh>
Expand All @@ -56,17 +57,10 @@
#include "gz/gui/Helpers.hh"
#include "gz/gui/MainWindow.hh"

#define GZ_GUI_HAVE_VULKAN \
QT_VERSION >= QT_VERSION_CHECK(5, 15, 2) && \
QT_CONFIG(vulkan) && \
GZ_RENDERING_HAVE_VULKAN

#define GZ_GUI_HAVE_METAL __APPLE__

#if GZ_GUI_HAVE_VULKAN
# include <QVulkanInstance>
# include <gz/rendering/RenderEngineVulkanExternalDeviceStructs.hh>
#endif // GZ_HAVE_VULKAN
#endif // GZ_GUI_HAVE_VULKAN

Q_DECLARE_METATYPE(gz::gui::plugins::RenderSync*)

Expand Down Expand Up @@ -232,7 +226,7 @@ class gz::gui::plugins::RenderWindowItem::Implementation
rendering::GraphicsAPI::VULKAN;
#elif MINIMAL_SCENE_HAVE_OPENGL
rendering::GraphicsAPI::OPENGL;
#endif
#endif // GZ_GUI_HAVE_METAL

/// \brief Render thread
public: RenderThread *renderThread = nullptr;
Expand Down Expand Up @@ -1195,6 +1189,29 @@ QSGNode *RenderWindowItem::updatePaintNode(QSGNode *_node,

if (this->dataPtr->graphicsAPI == rendering::GraphicsAPI::OPENGL)
{
auto *rif = this->window()->rendererInterface();
Q_ASSERT(rif->graphicsApi() == QSGRendererInterface::OpenGL);

auto *current = static_cast<QOpenGLContext*>(
rif->getResource(this->window(),
QSGRendererInterface::OpenGLContextResource));

// Some GL implementations require that the currently bound context is
// made non-current before we set up sharing, so we doneCurrent here
// and makeCurrent down below while setting up our own context.
current->doneCurrent();

this->dataPtr->renderThread->SetContext(new QOpenGLContext());
this->dataPtr->renderThread->Context()->setFormat(current->format());
this->dataPtr->renderThread->Context()->setShareContext(current);
this->dataPtr->renderThread->Context()->create();

// The slot "Ready" runs on the main thread, move the context to match
this->dataPtr->renderThread->Context()->moveToThread(
QApplication::instance()->thread());

current->makeCurrent(this->window());

// Initialize on main thread
QMetaObject::invokeMethod(this, "Ready", Qt::QueuedConnection);
}
Expand Down
140 changes: 70 additions & 70 deletions src/plugins/minimal_scene/MinimalScene.hh
Original file line number Diff line number Diff line change
Expand Up @@ -380,108 +380,108 @@ namespace gz::gui::plugins
/// \param[in] _view_controller The camera view controller type to set
public: void SetCameraViewController(const std::string &_view_controller);

/// \brief Slot called when thread is ready to be started
public Q_SLOTS: void Ready();
/// \brief Slot called when thread is ready to be started
public Q_SLOTS: void Ready();

/// \brief Handle key press event for snapping
/// \param[in] _e The key event to process.
public: void HandleKeyPress(const common::KeyEvent &_e);
/// \brief Handle key press event for snapping
/// \param[in] _e The key event to process.
public: void HandleKeyPress(const common::KeyEvent &_e);

/// \brief Handle key release event for snapping
/// \param[in] _e The key event to process.
public: void HandleKeyRelease(const common::KeyEvent &_e);
/// \brief Handle key release event for snapping
/// \param[in] _e The key event to process.
public: void HandleKeyRelease(const common::KeyEvent &_e);

/// \brief Set a callback to be called in case there are errors.
/// \param[in] _cb Error callback
public: void SetErrorCb(std::function<void(const QString &)> _cb);
/// \brief Set a callback to be called in case there are errors.
/// \param[in] _cb Error callback
public: void SetErrorCb(std::function<void(const QString &)> _cb);

/// \brief Stop rendering and shutdown resources.
public: void StopRendering();
/// \brief Stop rendering and shutdown resources.
public: void StopRendering();

// Documentation inherited
protected: virtual void mousePressEvent(QMouseEvent *_e) override;
// Documentation inherited
protected: virtual void mousePressEvent(QMouseEvent *_e) override;

// Documentation inherited
protected: virtual void mouseReleaseEvent(QMouseEvent *_e) override;
// Documentation inherited
protected: virtual void mouseReleaseEvent(QMouseEvent *_e) override;

// Documentation inherited
protected: virtual void mouseMoveEvent(QMouseEvent *_e) override;
// Documentation inherited
protected: virtual void mouseMoveEvent(QMouseEvent *_e) override;

// Documentation inherited
protected: virtual void keyPressEvent(QKeyEvent *_e) override;
// Documentation inherited
protected: virtual void keyPressEvent(QKeyEvent *_e) override;

// Documentation inherited
protected: virtual void keyReleaseEvent(QKeyEvent *_e) override;
// Documentation inherited
protected: virtual void keyReleaseEvent(QKeyEvent *_e) override;

// Documentation inherited
protected: virtual void wheelEvent(QWheelEvent *_e) override;
// Documentation inherited
protected: virtual void wheelEvent(QWheelEvent *_e) override;

/// \brief Overrides the paint event to render the render engine
/// camera view
/// \param[in] _oldNode The node passed in previous updatePaintNode
/// function. It represents the visual representation of the item.
/// \param[in] _data The node transformation data.
/// \return Updated node.
private: QSGNode *updatePaintNode(QSGNode *_oldNode,
QQuickItem::UpdatePaintNodeData *_data) override;
/// \brief Overrides the paint event to render the render engine
/// camera view
/// \param[in] _oldNode The node passed in previous updatePaintNode
/// function. It represents the visual representation of the item.
/// \param[in] _data The node transformation data.
/// \return Updated node.
private: QSGNode *updatePaintNode(QSGNode *_oldNode,
QQuickItem::UpdatePaintNodeData *_data) override;

/// \internal
/// \brief Pointer to private data.
GZ_UTILS_UNIQUE_IMPL_PTR(dataPtr)
/// \internal
/// \brief Pointer to private data.
GZ_UTILS_UNIQUE_IMPL_PTR(dataPtr)
};

/// \brief Texture node for displaying the render texture from gz-renderer
class TextureNode : public QObject, public QSGSimpleTextureNode
{
Q_OBJECT
Q_OBJECT

/// \brief Constructor
/// \param[in] _window Window to display the texture
/// \param[in] _renderSync RenderSync to safely
/// synchronize Qt (this) and worker thread
/// \param[in] _graphicsAPI The type of graphics API
/// \param[in] _camera Camera owning the Texture Handle
public: explicit TextureNode(QQuickWindow *_window,
RenderSync &_renderSync,
const rendering::GraphicsAPI &_graphicsAPI,
rendering::CameraPtr &_camera);
/// \brief Constructor
/// \param[in] _window Window to display the texture
/// \param[in] _renderSync RenderSync to safely
/// synchronize Qt (this) and worker thread
/// \param[in] _graphicsAPI The type of graphics API
/// \param[in] _camera Camera owning the Texture Handle
public: explicit TextureNode(QQuickWindow *_window,
RenderSync &_renderSync,
const rendering::GraphicsAPI &_graphicsAPI,
rendering::CameraPtr &_camera);

/// \brief Destructor
public: ~TextureNode() override;
/// \brief Destructor
public: ~TextureNode() override;

/// \brief This function gets called on the FBO rendering thread and will
/// store the texture id and size and schedule an update on the window.
/// \param[in] _texturePtr Pointer to a texture Id
/// \param[in] _size Texture size
// public slots: void NewTexture(uint _id, const QSize &_size);
public slots: void NewTexture(void* _texturePtr, const QSize &_size);
/// \brief This function gets called on the FBO rendering thread and will
/// store the texture id and size and schedule an update on the window.
/// \param[in] _texturePtr Pointer to a texture Id
/// \param[in] _size Texture size
// public slots: void NewTexture(uint _id, const QSize &_size);
public slots: void NewTexture(void* _texturePtr, const QSize &_size);

/// \brief Before the scene graph starts to render, we update to the
/// pending texture
public slots: void PrepareNode();
/// \brief Before the scene graph starts to render, we update to the
/// pending texture
public slots: void PrepareNode();

/// \param[in] _renderSync RenderSync to send to the worker thread
signals: void TextureInUse(gz::gui::plugins::RenderSync *_renderSync);
/// \param[in] _renderSync RenderSync to send to the worker thread
signals: void TextureInUse(gz::gui::plugins::RenderSync *_renderSync);

/// \brief Signal emitted when a new texture is ready to trigger window
/// update
signals: void PendingNewTexture();
/// \brief Signal emitted when a new texture is ready to trigger window
/// update
signals: void PendingNewTexture();

/// \brief Texture size
public: QSize size = QSize(0, 0);
/// \brief Texture size
public: QSize size = QSize(0, 0);

/// \brief Mutex to protect the texture variables
public: QMutex mutex;
/// \brief Mutex to protect the texture variables
public: QMutex mutex;

/// \brief See RenderSync
public: RenderSync &renderSync;
/// \brief See RenderSync
public: RenderSync &renderSync;

/// \brief Qt quick window
public: QQuickWindow *window = nullptr;

/// \brief Pointer to render interface to handle OpenGL/Metal compatibility
private: std::unique_ptr<TextureNodeRhi> rhi;
};
};
} // namespace gz::gui::plugins

#endif // GZ_GUI_PLUGINS_MINIMALSCENE_HH_
7 changes: 7 additions & 0 deletions src/plugins/minimal_scene/MinimalSceneRhi.hh
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@
#include <QSGTexture>
#include <QSize>

#define GZ_GUI_HAVE_VULKAN \
QT_VERSION >= QT_VERSION_CHECK(5, 15, 2) && \
QT_CONFIG(vulkan) && \
GZ_RENDERING_HAVE_VULKAN

#define GZ_GUI_HAVE_METAL __APPLE__

namespace gz::gui::plugins
{
/// \brief Render interface class to handle OpenGL / Metal compatibility
Expand Down
Loading

0 comments on commit a5ed392

Please sign in to comment.