Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OpenGL viewport assertion when trying to embed GLWidget in parent window #184

Open
lechmazur opened this issue Nov 26, 2024 · 3 comments
Open

Comments

@lechmazur
Copy link

I'm trying to embed QMapLibre::GLWidget as a child widget in my Qt application's main window, but running into OpenGL viewport assertions.

The assertion happens in mbgl::gl::RendererBackend::assumeViewport() when the widget is being shown as part of the parent window's widget hierarchy. I noticed in the docs that GLWidget is described as "intended as a standalone map viewer", but I wanted to confirm if this is a known limitation. Are there any workarounds to properly embed it in a parent window? Is separate window approach the best solution? Any guidance would be appreciated.

Environment:
Qt 6.8
Windows 10

@ntadej
Copy link
Collaborator

ntadej commented Nov 26, 2024

What the "standalone map viewer" means is that you also get the map instance with it (so you just add the widget and get everything). You can certainly put it as child in the UI. Actually the example that we use even supports docked windows.

How do you run your Windows app? You need to force OpenGL and not use DirectX (which I think is the default in Qt 6).

@lechmazur
Copy link
Author

lechmazur commented Nov 26, 2024

Thank you for the quick response!

I believe I know the reason for this discrepancy: the assertion occurs only in Debug mode.

I started with a new, empty Qt Widgets template project in Visual Studio. Adding the following code to the constructor is enough to trigger the assertion:

TestMaps::TestMaps(QWidget *parent) : QMainWindow(parent) {
    ui.setupUi(this);
    
    // Setup map styles and settings
    QMapLibre::Styles styles;
    styles.emplace_back("https://demotiles.maplibre.org/style.json", "Demo Tiles");

    QMapLibre::Settings settings;
    settings.setStyles(styles);
    settings.setDefaultZoom(5);
    settings.setDefaultCoordinate(QMapLibre::Coordinate(43, 21));

    // Create and setup map widget
    m_mapWidget = std::make_unique<QMapLibre::GLWidget>(settings);
    
    // Set the map widget as the central widget
    setCentralWidget(m_mapWidget.get());
    
    setWindowTitle(tr("TestMaps with QMapLibre"));
}

The example code from the source added to the empty Qt project runs fine in Release mode but asserts in Debug mode when the window is resized. The assertion occurs here:

	QMapLibred.dll!mbgl::gl::RendererBackend::assumeViewport(int x, int y, const mbgl::Size & size) Line 34	C++
 	QMapLibred.dll!QMapLibre::RendererBackend::updateAssumedState() Line 35	C++
 	QMapLibred.dll!mbgl::gl::Context::createCommandEncoder() Line 586	C++
 	QMapLibred.dll!mbgl::PaintParameters::PaintParameters(mbgl::gfx::Context & context_, float pixelRatio_, mbgl::gfx::RendererBackend & backend_, const mbgl::style::Properties<mbgl::style::LightAnchor,mbgl::style::LightPosition,mbgl::style::LightColor,mbgl::style::LightIntensity>::PossiblyEvaluated & evaluatedLight_, mbgl::MapMode mode_, mbgl::MapDebugOptions debugOptions_, std::chrono::time_point<std::chrono::steady_clock,std::chrono::duration<__int64,std::ratio<1,1000000000>>> timePoint_, const mbgl::TransformParameters & transformParams_, mbgl::RenderStaticData & staticData_, mbgl::LineAtlas & lineAtlas_, mbgl::PatternAtlas & patternAtlas_) Line 42	C++
 	QMapLibred.dll!mbgl::Renderer::Impl::render(const mbgl::RenderTree & renderTree) Line 64	C++
 	QMapLibred.dll!mbgl::Renderer::render(const std::shared_ptr<mbgl::UpdateParameters> & updateParameters) Line 32	C++
 	QMapLibred.dll!QMapLibre::MapRenderer::render() Line 97	C++
 	QMapLibred.dll!QMapLibre::MapPrivate::render() Line 1734	C++
 	QMapLibred.dll!QMapLibre::Map::render() Line 1545	C++
 	QMapLibreWidgetsd.dll!QMapLibre::GLWidget::paintGL() Line 137	C++
 	Qt6OpenGLWidgetsd.dll!QOpenGLWidgetPrivate::render() Line 978	C++
 	Qt6OpenGLWidgetsd.dll!QOpenGLWidget::paintEvent(QPaintEvent * e) Line 1538	C++
 	Qt6Widgetsd.dll!QWidget::event(QEvent * event) Line 9125	C++
 	Qt6OpenGLWidgetsd.dll!QOpenGLWidget::event(QEvent * e) Line 1743	C++
 	Qt6Widgetsd.dll!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e) Line 3294	C++
 	Qt6Widgetsd.dll!QApplication::notify(QObject * receiver, QEvent * e) Line 3241	C++
 	Qt6Cored.dll!QCoreApplication::notifyInternal2(QObject * receiver, QEvent * event) Line 1165	C++
 	Qt6Cored.dll!QCoreApplication::sendSpontaneousEvent(QObject * receiver, QEvent * event) Line 1624	C++
 	Qt6Widgetsd.dll!QWidgetPrivate::sendPaintEvent(const QRegion & toBePainted) Line 5658	C++
 	Qt6Widgetsd.dll!QWidgetRepaintManager::paintAndFlush() Line 826	C++
 	Qt6Widgetsd.dll!QWidgetRepaintManager::sync() Line 660	C++
 	Qt6Widgetsd.dll!QWidgetPrivate::syncBackingStore() Line 1768	C++
 	Qt6Widgetsd.dll!QWidget::event(QEvent * event) Line 9289	C++
 	Qt6Widgetsd.dll!QMainWindow::event(QEvent * event) Line 1313	C++
 	Qt6Widgetsd.dll!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e) Line 3294	C++
 	Qt6Widgetsd.dll!QApplication::notify(QObject * receiver, QEvent * e) Line 3241	C++
 	Qt6Cored.dll!QCoreApplication::notifyInternal2(QObject * receiver, QEvent * event) Line 1165	C++
 	Qt6Cored.dll!QCoreApplication::sendEvent(QObject * receiver, QEvent * event) Line 1610	C++
 	Qt6Cored.dll!QCoreApplicationPrivate::sendPostedEvents(QObject * receiver, int event_type, QThreadData * data) Line 1965	C++
 	Qt6Cored.dll!QEventDispatcherWin32::sendPostedEvents() Line 900	C++
 	Qt6Guid.dll!QWindowsGuiEventDispatcher::sendPostedEvents() Line 44	C++
 	Qt6Cored.dll!qt_internal_proc(HWND__ * hwnd, unsigned int message, unsigned __int64 wp, __int64 lp) Line 205	C++
 	[External Code]	
 	QMapLibred.dll!mbgl::gl::RendererBackend::assumeViewport(int x, int y, const mbgl::Size & size) Line 34	C++
 	QMapLibred.dll!QMapLibre::RendererBackend::updateAssumedState() Line 35	C++
 	QMapLibred.dll!mbgl::gl::Context::createCommandEncoder() Line 586	C++
 	QMapLibred.dll!mbgl::PaintParameters::PaintParameters(mbgl::gfx::Context & context_, float pixelRatio_, mbgl::gfx::RendererBackend & backend_, const mbgl::style::Properties<mbgl::style::LightAnchor,mbgl::style::LightPosition,mbgl::style::LightColor,mbgl::style::LightIntensity>::PossiblyEvaluated & evaluatedLight_, mbgl::MapMode mode_, mbgl::MapDebugOptions debugOptions_, std::chrono::time_point<std::chrono::steady_clock,std::chrono::duration<__int64,std::ratio<1,1000000000>>> timePoint_, const mbgl::TransformParameters & transformParams_, mbgl::RenderStaticData & staticData_, mbgl::LineAtlas & lineAtlas_, mbgl::PatternAtlas & patternAtlas_) Line 42	C++
 	QMapLibred.dll!mbgl::Renderer::Impl::render(const mbgl::RenderTree & renderTree) Line 64	C++
 	QMapLibred.dll!mbgl::Renderer::render(const std::shared_ptr<mbgl::UpdateParameters> & updateParameters) Line 32	C++
 	QMapLibred.dll!QMapLibre::MapRenderer::render() Line 97	C++
 	QMapLibred.dll!QMapLibre::MapPrivate::render() Line 1734	C++
 	QMapLibred.dll!QMapLibre::Map::render() Line 1545	C++
 	QMapLibreWidgetsd.dll!QMapLibre::GLWidget::paintGL() Line 137	C++
 	Qt6OpenGLWidgetsd.dll!QOpenGLWidgetPrivate::render() Line 978	C++
 	Qt6OpenGLWidgetsd.dll!QOpenGLWidget::paintEvent(QPaintEvent * e) Line 1538	C++
 	Qt6Widgetsd.dll!QWidget::event(QEvent * event) Line 9125	C++
 	Qt6OpenGLWidgetsd.dll!QOpenGLWidget::event(QEvent * e) Line 1743	C++
 	Qt6Widgetsd.dll!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e) Line 3294	C++
 	Qt6Widgetsd.dll!QApplication::notify(QObject * receiver, QEvent * e) Line 3241	C++
 	Qt6Cored.dll!QCoreApplication::notifyInternal2(QObject * receiver, QEvent * event) Line 1165	C++
 	Qt6Cored.dll!QCoreApplication::sendSpontaneousEvent(QObject * receiver, QEvent * event) Line 1624	C++
 	Qt6Widgetsd.dll!QWidgetPrivate::sendPaintEvent(const QRegion & toBePainted) Line 5658	C++
 	Qt6Widgetsd.dll!QWidgetPrivate::drawWidget(QPaintDevice * pdev, const QRegion & rgn, const QPoint & offset, QFlags<enum QWidgetPrivate::DrawWidgetFlag> flags, QPainter * sharedPainter, QWidgetRepaintManager * repaintManager) Line 5609	C++
 	Qt6Widgetsd.dll!QWidgetPrivate::paintSiblingsRecursive(QPaintDevice * pdev, const QList<QObject *> & siblings, int index, const QRegion & rgn, const QPoint & offset, QFlags<enum QWidgetPrivate::DrawWidgetFlag> flags, QPainter * sharedPainter, QWidgetRepaintManager * repaintManager) Line 5786	C++
 	Qt6Widgetsd.dll!QWidgetPrivate::paintSiblingsRecursive(QPaintDevice * pdev, const QList<QObject *> & siblings, int index, const QRegion & rgn, const QPoint & offset, QFlags<enum QWidgetPrivate::DrawWidgetFlag> flags, QPainter * sharedPainter, QWidgetRepaintManager * repaintManager) Line 5773	C++
 	Qt6Widgetsd.dll!QWidgetPrivate::drawWidget(QPaintDevice * pdev, const QRegion & rgn, const QPoint & offset, QFlags<enum QWidgetPrivate::DrawWidgetFlag> flags, QPainter * sharedPainter, QWidgetRepaintManager * repaintManager) Line 5650	C++
 	Qt6Widgetsd.dll!QWidgetPrivate::paintSiblingsRecursive(QPaintDevice * pdev, const QList<QObject *> & siblings, int index, const QRegion & rgn, const QPoint & offset, QFlags<enum QWidgetPrivate::DrawWidgetFlag> flags, QPainter * sharedPainter, QWidgetRepaintManager * repaintManager) Line 5786	C++
 	Qt6Widgetsd.dll!QWidgetPrivate::drawWidget(QPaintDevice * pdev, const QRegion & rgn, const QPoint & offset, QFlags<enum QWidgetPrivate::DrawWidgetFlag> flags, QPainter * sharedPainter, QWidgetRepaintManager * repaintManager) Line 5650	C++
 	Qt6Widgetsd.dll!QWidgetRepaintManager::paintAndFlush() Line 910	C++
 	Qt6Widgetsd.dll!QWidgetRepaintManager::sync() Line 660	C++
 	Qt6Widgetsd.dll!QWidgetPrivate::syncBackingStore() Line 1768	C++
 	Qt6Widgetsd.dll!QWidget::event(QEvent * event) Line 9289	C++
 	Qt6Widgetsd.dll!QMainWindow::event(QEvent * event) Line 1313	C++
 	Qt6Widgetsd.dll!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e) Line 3294	C++
 	Qt6Widgetsd.dll!QApplication::notify(QObject * receiver, QEvent * e) Line 3241	C++
 	Qt6Cored.dll!QCoreApplication::notifyInternal2(QObject * receiver, QEvent * event) Line 1165	C++
 	Qt6Cored.dll!QCoreApplication::sendEvent(QObject * receiver, QEvent * event) Line 1610	C++
 	Qt6Cored.dll!QCoreApplicationPrivate::sendPostedEvents(QObject * receiver, int event_type, QThreadData * data) Line 1965	C++
 	Qt6Cored.dll!QEventDispatcherWin32::sendPostedEvents() Line 900	C++
 	Qt6Guid.dll!QWindowsGuiEventDispatcher::sendPostedEvents() Line 44	C++
 	Qt6Cored.dll!qt_internal_proc(HWND__ * hwnd, unsigned int message, unsigned __int64 wp, __int64 lp) Line 192	C++
 	[External Code]	
 	QMapLibred.dll!mbgl::gl::RendererBackend::assumeViewport(int x, int y, const mbgl::Size & size) Line 34	C++
 	QMapLibred.dll!QMapLibre::RendererBackend::updateAssumedState() Line 35	C++
 	QMapLibred.dll!mbgl::gl::Context::createCommandEncoder() Line 586	C++
 	QMapLibred.dll!mbgl::PaintParameters::PaintParameters(mbgl::gfx::Context & context_, float pixelRatio_, mbgl::gfx::RendererBackend & backend_, const mbgl::style::Properties<mbgl::style::LightAnchor,mbgl::style::LightPosition,mbgl::style::LightColor,mbgl::style::LightIntensity>::PossiblyEvaluated & evaluatedLight_, mbgl::MapMode mode_, mbgl::MapDebugOptions debugOptions_, std::chrono::time_point<std::chrono::steady_clock,std::chrono::duration<__int64,std::ratio<1,1000000000>>> timePoint_, const mbgl::TransformParameters & transformParams_, mbgl::RenderStaticData & staticData_, mbgl::LineAtlas & lineAtlas_, mbgl::PatternAtlas & patternAtlas_) Line 42	C++
 	QMapLibred.dll!mbgl::Renderer::Impl::render(const mbgl::RenderTree & renderTree) Line 64	C++
 	QMapLibred.dll!mbgl::Renderer::render(const std::shared_ptr<mbgl::UpdateParameters> & updateParameters) Line 32	C++
 	QMapLibred.dll!QMapLibre::MapRenderer::render() Line 97	C++
 	QMapLibred.dll!QMapLibre::MapPrivate::render() Line 1734	C++
 	QMapLibred.dll!QMapLibre::Map::render() Line 1545	C++
 	QMapLibreWidgetsd.dll!QMapLibre::GLWidget::paintGL() Line 137	C++
 	Qt6OpenGLWidgetsd.dll!QOpenGLWidgetPrivate::render() Line 978	C++
 	Qt6OpenGLWidgetsd.dll!QOpenGLWidget::paintEvent(QPaintEvent * e) Line 1538	C++
 	Qt6Widgetsd.dll!QWidget::event(QEvent * event) Line 9125	C++
 	Qt6OpenGLWidgetsd.dll!QOpenGLWidget::event(QEvent * e) Line 1743	C++
 	Qt6Widgetsd.dll!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e) Line 3294	C++
 	Qt6Widgetsd.dll!QApplication::notify(QObject * receiver, QEvent * e) Line 3241	C++
 	Qt6Cored.dll!QCoreApplication::notifyInternal2(QObject * receiver, QEvent * event) Line 1165	C++
 	Qt6Cored.dll!QCoreApplication::sendSpontaneousEvent(QObject * receiver, QEvent * event) Line 1624	C++
 	Qt6Widgetsd.dll!QWidgetPrivate::sendPaintEvent(const QRegion & toBePainted) Line 5658	C++
 	Qt6OpenGLWidgetsd.dll!QOpenGLWidget::resizeEvent(QResizeEvent * e) Line 1513	C++
 	Qt6Widgetsd.dll!QWidget::event(QEvent * event) Line 9134	C++
 	Qt6OpenGLWidgetsd.dll!QOpenGLWidget::event(QEvent * e) Line 1743	C++
 	Qt6Widgetsd.dll!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e) Line 3294	C++
 	Qt6Widgetsd.dll!QApplication::notify(QObject * receiver, QEvent * e) Line 3241	C++
 	Qt6Cored.dll!QCoreApplication::notifyInternal2(QObject * receiver, QEvent * event) Line 1165	C++
 	Qt6Cored.dll!QCoreApplication::sendEvent(QObject * receiver, QEvent * event) Line 1610	C++
 	Qt6Widgetsd.dll!QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) Line 7338	C++
 	Qt6Widgetsd.dll!QWidget::setGeometry(const QRect & r) Line 7226	C++
 	Qt6Widgetsd.dll!QWidget::setGeometry(int ax, int ay, int aw, int ah) Line 888	C++
 	Qt6Widgetsd.dll!QWidgetItem::setGeometry(const QRect & rect) Line 479	C++
 	Qt6Widgetsd.dll!QBoxLayout::setGeometry(const QRect & r) Line 792	C++
 	Qt6Widgetsd.dll!QLayoutPrivate::doResize() Line 508	C++
 	Qt6Widgetsd.dll!QLayout::widgetEvent(QEvent * e) Line 530	C++
 	Qt6Widgetsd.dll!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e) Line 3288	C++
 	Qt6Widgetsd.dll!QApplication::notify(QObject * receiver, QEvent * e) Line 3241	C++
 	Qt6Cored.dll!QCoreApplication::notifyInternal2(QObject * receiver, QEvent * event) Line 1165	C++
 	Qt6Cored.dll!QCoreApplication::sendEvent(QObject * receiver, QEvent * event) Line 1610	C++
 	Qt6Widgetsd.dll!QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) Line 7338	C++
 	Qt6Widgetsd.dll!QWidget::setGeometry(const QRect & r) Line 7226	C++
 	Qt6Widgetsd.dll!QWidget::qt_static_metacall(QObject * _o, QMetaObject::Call _c, int _id, void * * _a) Line 638	C++
 	Qt6Widgetsd.dll!QWidget::qt_metacall(QMetaObject::Call _c, int _id, void * * _a) Line 724	C++
 	TestMaps.exe!Window::qt_metacall(QMetaObject::Call _c, int _id, void * * _a) Line 112	C++
 	Qt6Cored.dll!QMetaObject::metacall(QObject * object, QMetaObject::Call cl, int idx, void * * argv) Line 335	C++
 	Qt6Cored.dll!QPropertyAnimationPrivate::updateProperty(const QVariant & newValue) Line 106	C++
 	Qt6Cored.dll!QPropertyAnimation::updateCurrentValue(const QVariant & value) Line 238	C++
 	Qt6Cored.dll!QVariantAnimationPrivate::setCurrentValueForProgress(const double progress) Line 255	C++
 	Qt6Cored.dll!QVariantAnimationPrivate::recalculateCurrentInterval(bool force) Line 237	C++
 	Qt6Cored.dll!QVariantAnimationPrivate::setDefaultStartEndValue(const QVariant & value) Line 302	C++
 	Qt6Cored.dll!QPropertyAnimation::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState) Line 284	C++
 	Qt6Cored.dll!QAbstractAnimationPrivate::setState(QAbstractAnimation::State newState) Line 948	C++
 	Qt6Cored.dll!QAbstractAnimation::start(QAbstractAnimation::DeletionPolicy policy) Line 1389	C++
 	Qt6Widgetsd.dll!QWidgetAnimator::animate(QWidget * widget, const QRect & _final_geometry, bool animate) Line 79	C++
 	Qt6Widgetsd.dll!QDockAreaLayout::apply(bool animate) Line 3272	C++
 	Qt6Widgetsd.dll!QMainWindowLayoutState::apply(bool animated) Line 861	C++
 	Qt6Widgetsd.dll!QMainWindowLayout::applyState(QMainWindowLayoutState & newState, bool animate) Line 3221	C++
 	Qt6Widgetsd.dll!QMainWindowLayout::setGeometry(const QRect & _r) Line 2351	C++
 	Qt6Widgetsd.dll!QLayoutPrivate::doResize() Line 508	C++
 	Qt6Widgetsd.dll!QLayout::widgetEvent(QEvent * e) Line 530	C++
 	Qt6Widgetsd.dll!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e) Line 3288	C++
 	Qt6Widgetsd.dll!QApplication::notify(QObject * receiver, QEvent * e) Line 3241	C++
 	Qt6Cored.dll!QCoreApplication::notifyInternal2(QObject * receiver, QEvent * event) Line 1165	C++
 	Qt6Cored.dll!QCoreApplication::forwardEvent(QObject * receiver, QEvent * event, QEvent * originatingEvent) Line 1181	C++
 	Qt6Widgetsd.dll!QWidgetWindow::handleResizeEvent(QResizeEvent * event) Line 802	C++
 	Qt6Widgetsd.dll!QWidgetWindow::event(QEvent * event) Line 321	C++
 	Qt6Widgetsd.dll!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e) Line 3294	C++
 	Qt6Widgetsd.dll!QApplication::notify(QObject * receiver, QEvent * e) Line 3245	C++
 	Qt6Cored.dll!QCoreApplication::notifyInternal2(QObject * receiver, QEvent * event) Line 1165	C++
 	Qt6Cored.dll!QCoreApplication::sendSpontaneousEvent(QObject * receiver, QEvent * event) Line 1624	C++
 	Qt6Guid.dll!QGuiApplicationPrivate::processGeometryChangeEvent(QWindowSystemInterfacePrivate::GeometryChangeEvent * e) Line 2854	C++
 	Qt6Guid.dll!QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent * e) Line 2201	C++
 	Qt6Guid.dll!QWindowSystemInterface::sendWindowSystemEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 1120	C++
 	Qt6Guid.dll!QWindowSystemInterface::flushWindowSystemEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 1085	C++
 	qwindowsd.dll!QWindowsWindow::handleWmPaint(HWND__ * hwnd, unsigned int message, unsigned __int64 __formal, __int64 __formal, __int64 * result) Line 2423	C++
 	qwindowsd.dll!QWindowsContext::windowsProc(HWND__ * hwnd, unsigned int message, QtWindows::WindowsEventType et, unsigned __int64 wParam, __int64 lParam, __int64 * result, QWindowsWindow * * platformWindowPtr) Line 1174	C++
 	qwindowsd.dll!qWindowsWndProc(HWND__ * hwnd, unsigned int message, unsigned __int64 wParam, __int64 lParam) Line 1501	C++
 	[External Code]	
 	qwindowsd.dll!qWindowsWndProc(HWND__ * hwnd, unsigned int message, unsigned __int64 wParam, __int64 lParam) Line 1511	C++
 	[External Code]	
 	qwindowsd.dll!qWindowsWndProc(HWND__ * hwnd, unsigned int message, unsigned __int64 wParam, __int64 lParam) Line 1511	C++
 	[External Code]	
 	Qt6Cored.dll!QEventDispatcherWin32::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 539	C++
 	Qt6Guid.dll!QWindowsGuiEventDispatcher::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 36	C++
 	Qt6Cored.dll!QEventLoop::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 101	C++
 	Qt6Cored.dll!QEventLoop::exec(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 191	C++
 	Qt6Cored.dll!QCoreApplication::exec() Line 1510	C++
 	Qt6Guid.dll!QGuiApplication::exec() Line 1976	C++
 	Qt6Widgetsd.dll!QApplication::exec() Line 2563	C++
 	TestMaps.exe!main(int argc, char * * argv) Line 9	C++
 	TestMaps.exe!qtEntryPoint() Line 45	C++
 	TestMaps.exe!WinMain(HINSTANCE__ * __formal, HINSTANCE__ * __formal, char * __formal, int __formal) Line 64	C++

Note that when attempting to run the example created using CMake/Ninja, I got the following error: "This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem" after copying over the library and the Qt DLLs, so I haven't been actually able to test the widget example source code in this exact setup.

In my initial tests, everything worked fine in Debug mode when launched in a standalone window. However, the issue arose when I embedded it as a child window.

Please let me know and I can send over this minimal repro.

@lechmazur
Copy link
Author

I think I've identified the root cause of the viewport assertion. It's happening due to a DPI scaling rounding mismatch between Qt and OpenGL. In my case with a 150% DPI scaling Qt rounds up the scaled dimensions while OpenGL truncates them:

// Example from my debug logs:
Widget size: 2251x1347
After DPI scaling (1.5):

  • Qt rounds up: 3377x2021
  • OpenGL truncates: 3376x2020

This 1-pixel difference triggers the assertion in debug builds.

Something like this might help:

void GLWidget::paintGL() {
    QSize currentSize = size();
    float dpr = devicePixelRatioF();
    
    QSize fbSize(
        std::floor(currentSize.width() * dpr),
        std::floor(currentSize.height() * dpr)
    );
    
    d_ptr->m_map->resize(currentSize);
    d_ptr->m_map->setOpenGLFramebufferObject(defaultFramebufferObject(), fbSize);
    d_ptr->m_map->render();
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants