From 05bb156aaad8b539e9b28a6c7577e48319e281ba Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 12 Jul 2019 15:28:14 +0200 Subject: Windows QPA: Fix emitting of QScreen's changed signals When changing the primary screen, the various changed signals of QScreen were out of order. Most notably, the wrong DPI value was emitted since QGuiApplicationPrivate::processScreenGeometryChange() checks and emits DPI and orientation as well. Rearrange the code to assign new the values and emit DPI first. Task-number: QTBUG-76902 Change-Id: If4037108391c36ab3a8bfcb9b2989d5bea41202f Reviewed-by: Oliver Wolff --- src/plugins/platforms/windows/qwindowsscreen.cpp | 31 ++++++++++++++---------- 1 file changed, 18 insertions(+), 13 deletions(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp index cc0f3c1a6e..4137a4bd9a 100644 --- a/src/plugins/platforms/windows/qwindowsscreen.cpp +++ b/src/plugins/platforms/windows/qwindowsscreen.cpp @@ -303,23 +303,28 @@ void QWindowsScreen::handleChanges(const QWindowsScreenData &newData) m_data.hMonitor = newData.hMonitor; } - if (m_data.geometry != newData.geometry || m_data.availableGeometry != newData.availableGeometry) { - m_data.geometry = newData.geometry; - m_data.availableGeometry = newData.availableGeometry; - QWindowSystemInterface::handleScreenGeometryChange(screen(), - newData.geometry, newData.availableGeometry); - } - if (!qFuzzyCompare(m_data.dpi.first, newData.dpi.first) - || !qFuzzyCompare(m_data.dpi.second, newData.dpi.second)) { - m_data.dpi = newData.dpi; + // QGuiApplicationPrivate::processScreenGeometryChange() checks and emits + // DPI and orientation as well, so, assign new values and emit DPI first. + const bool geometryChanged = m_data.geometry != newData.geometry + || m_data.availableGeometry != newData.availableGeometry; + const bool dpiChanged = !qFuzzyCompare(m_data.dpi.first, newData.dpi.first) + || !qFuzzyCompare(m_data.dpi.second, newData.dpi.second); + const bool orientationChanged = m_data.orientation != newData.orientation; + m_data.dpi = newData.dpi; + m_data.orientation = newData.orientation; + m_data.geometry = newData.geometry; + m_data.availableGeometry = newData.availableGeometry; + + if (dpiChanged) { QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(screen(), newData.dpi.first, newData.dpi.second); } - if (m_data.orientation != newData.orientation) { - m_data.orientation = newData.orientation; - QWindowSystemInterface::handleScreenOrientationChange(screen(), - newData.orientation); + if (orientationChanged) + QWindowSystemInterface::handleScreenOrientationChange(screen(), newData.orientation); + if (geometryChanged) { + QWindowSystemInterface::handleScreenGeometryChange(screen(), + newData.geometry, newData.availableGeometry); } } -- cgit v1.2.3 From 7a7fe9dbb3be042b42a559e734df40ffdea7ebbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 16 Jul 2019 23:19:19 +0200 Subject: macOS: Move QCocoaGLContext initialization into dedicated method Change-Id: I9dc2c400c3d26e9fcfaac04b61c1503229f59dba Reviewed-by: Timur Pocheptsov --- src/plugins/platforms/cocoa/qcocoaglcontext.h | 2 ++ src/plugins/platforms/cocoa/qcocoaglcontext.mm | 16 ++++++++++++---- src/plugins/platforms/cocoa/qcocoaintegration.mm | 4 +--- 3 files changed, 15 insertions(+), 7 deletions(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.h b/src/plugins/platforms/cocoa/qcocoaglcontext.h index c1041ac2da..bb309c0713 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.h +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.h @@ -56,6 +56,8 @@ public: QCocoaGLContext(QOpenGLContext *context); ~QCocoaGLContext(); + void initialize() override; + bool makeCurrent(QPlatformSurface *surface) override; void swapBuffers(QPlatformSurface *surface) override; void doneCurrent() override; diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm index d0100d0410..c0579c7c1e 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm @@ -76,9 +76,14 @@ QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(lcQpaOpenGLContext, "qt.qpa.openglcontext", QtWarningMsg); QCocoaGLContext::QCocoaGLContext(QOpenGLContext *context) - : QPlatformOpenGLContext(), m_format(context->format()) + : QPlatformOpenGLContext() + , m_format(context->format()) { - QVariant nativeHandle = context->nativeHandle(); +} + +void QCocoaGLContext::initialize() +{ + QVariant nativeHandle = context()->nativeHandle(); if (!nativeHandle.isNull()) { if (!nativeHandle.canConvert()) { qCWarning(lcQpaOpenGLContext, "QOpenGLContext native handle must be a QCocoaNativeContext"); @@ -95,7 +100,7 @@ QCocoaGLContext::QCocoaGLContext(QOpenGLContext *context) // Note: We have no way of knowing whether the NSOpenGLContext was created with the // share context as reported by the QOpenGLContext, but we just have to trust that // it was. It's okey, as the only thing we're using it for is to report isShared(). - if (QPlatformOpenGLContext *shareContext = context->shareHandle()) + if (QPlatformOpenGLContext *shareContext = context()->shareHandle()) m_shareContext = static_cast(shareContext)->nativeContext(); updateSurfaceFormat(); @@ -110,7 +115,7 @@ QCocoaGLContext::QCocoaGLContext(QOpenGLContext *context) if (m_format.renderableType() != QSurfaceFormat::OpenGL) return; - if (QPlatformOpenGLContext *shareContext = context->shareHandle()) { + if (QPlatformOpenGLContext *shareContext = context()->shareHandle()) { m_shareContext = static_cast(shareContext)->nativeContext(); // Allow sharing between 3.2 Core and 4.1 Core profile versions in @@ -150,6 +155,9 @@ QCocoaGLContext::QCocoaGLContext(QOpenGLContext *context) return; } + // The native handle should reflect the underlying context, even if we created it + context()->setNativeHandle(QVariant::fromValue(m_context)); + // --------------------- Set NSOpenGLContext properties --------------------- const GLint interval = m_format.swapInterval() >= 0 ? m_format.swapInterval() : 1; diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index b5d63f8331..dd2d1ba0f1 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -418,9 +418,7 @@ QPlatformOffscreenSurface *QCocoaIntegration::createPlatformOffscreenSurface(QOf #ifndef QT_NO_OPENGL QPlatformOpenGLContext *QCocoaIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const { - QCocoaGLContext *glContext = new QCocoaGLContext(context); - context->setNativeHandle(QVariant::fromValue(glContext->nativeContext())); - return glContext; + return new QCocoaGLContext(context); } #endif -- cgit v1.2.3 From d2e4bde5d09816ebedb1a5cc9ec7c0af20fd1242 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 16 Jul 2019 23:43:35 +0200 Subject: macOS: Use lambdas instead of Obj-C categories for GL helper functions Allows us to reference captured variables and keeps the function local to where it's used. Change-Id: I609892888720202021862d26a74ceb50e232f356 Reviewed-by: Timur Pocheptsov --- src/plugins/platforms/cocoa/qcocoaglcontext.mm | 46 +++++++++++--------------- 1 file changed, 20 insertions(+), 26 deletions(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm index c0579c7c1e..c5f0762ac2 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm @@ -53,24 +53,6 @@ static inline QByteArray getGlString(GLenum param) return QByteArray(); } -@implementation NSOpenGLPixelFormat (QtHelpers) -- (GLint)qt_getAttribute:(NSOpenGLPixelFormatAttribute)attribute -{ - int value = 0; - [self getValues:&value forAttribute:attribute forVirtualScreen:0]; - return value; -} -@end - -@implementation NSOpenGLContext (QtHelpers) -- (GLint)qt_getParameter:(NSOpenGLContextParameter)parameter -{ - int value = 0; - [self getValues:&value forParameter:parameter]; - return value; -} -@end - QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(lcQpaOpenGLContext, "qt.qpa.openglcontext", QtWarningMsg); @@ -293,7 +275,13 @@ void QCocoaGLContext::updateSurfaceFormat() NSOpenGLPixelFormat *pixelFormat = m_context.pixelFormat; - int colorSize = [pixelFormat qt_getAttribute:NSOpenGLPFAColorSize]; + auto pixelFormatAttribute = [&](NSOpenGLPixelFormatAttribute attribute) { + int value = 0; + [pixelFormat getValues:&value forAttribute:attribute forVirtualScreen:0]; + return value; + }; + + int colorSize = pixelFormatAttribute(NSOpenGLPFAColorSize); colorSize /= 4; // The attribute includes the alpha component m_format.setRedBufferSize(colorSize); m_format.setGreenBufferSize(colorSize); @@ -305,22 +293,28 @@ void QCocoaGLContext::updateSurfaceFormat() // size, as that will make the user believe the alpha channel can be used for // something useful, when in reality it can't, due to the surface being opaque. if (m_format.alphaBufferSize() > 0) - m_format.setAlphaBufferSize([pixelFormat qt_getAttribute:NSOpenGLPFAAlphaSize]); + m_format.setAlphaBufferSize(pixelFormatAttribute(NSOpenGLPFAAlphaSize)); - m_format.setDepthBufferSize([pixelFormat qt_getAttribute:NSOpenGLPFADepthSize]); - m_format.setStencilBufferSize([pixelFormat qt_getAttribute:NSOpenGLPFAStencilSize]); - m_format.setSamples([pixelFormat qt_getAttribute:NSOpenGLPFASamples]); + m_format.setDepthBufferSize(pixelFormatAttribute(NSOpenGLPFADepthSize)); + m_format.setStencilBufferSize(pixelFormatAttribute(NSOpenGLPFAStencilSize)); + m_format.setSamples(pixelFormatAttribute(NSOpenGLPFASamples)); - if ([pixelFormat qt_getAttribute:NSOpenGLPFATripleBuffer]) + if (pixelFormatAttribute(NSOpenGLPFATripleBuffer)) m_format.setSwapBehavior(QSurfaceFormat::TripleBuffer); - else if ([pixelFormat qt_getAttribute:NSOpenGLPFADoubleBuffer]) + else if (pixelFormatAttribute(NSOpenGLPFADoubleBuffer)) m_format.setSwapBehavior(QSurfaceFormat::DoubleBuffer); else m_format.setSwapBehavior(QSurfaceFormat::SingleBuffer); // ------------------- Query the context ------------------- - m_format.setSwapInterval([m_context qt_getParameter:NSOpenGLCPSwapInterval]); + auto glContextParameter = [&](NSOpenGLContextParameter parameter) { + int value = 0; + [m_context getValues:&value forParameter:parameter]; + return value; + }; + + m_format.setSwapInterval(glContextParameter(NSOpenGLCPSwapInterval)); if (oldContext) [oldContext makeCurrentContext]; -- cgit v1.2.3 From d224c762bc9530236d255cc5cb851112fcc7cee2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 16 Jul 2019 23:45:48 +0200 Subject: macOS: Use correct virtual screen when resolving GL surface format Change-Id: I8288db85c8e99bf9fccfcfbca7f9e3594d00fa48 Reviewed-by: Timur Pocheptsov --- src/plugins/platforms/cocoa/qcocoaglcontext.mm | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm index c5f0762ac2..e45ea7efd3 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm @@ -40,6 +40,8 @@ #include "qcocoaglcontext.h" #include "qcocoawindow.h" #include "qcocoahelpers.h" +#include "qcocoascreen.h" + #include #include #include @@ -275,9 +277,28 @@ void QCocoaGLContext::updateSurfaceFormat() NSOpenGLPixelFormat *pixelFormat = m_context.pixelFormat; + GLint virtualScreen = [&, this]() { + auto *platformScreen = static_cast(context()->screen()->handle()); + auto displayId = platformScreen->nativeScreen().qt_displayId; + auto requestedDisplay = CGDisplayIDToOpenGLDisplayMask(displayId); + for (int i = 0; i < pixelFormat.numberOfVirtualScreens; ++i) { + GLint supportedDisplays; + [pixelFormat getValues:&supportedDisplays forAttribute:NSOpenGLPFAScreenMask forVirtualScreen:i]; + // Note: The mask returned for NSOpenGLPFAScreenMask is a bit mask of + // physical displays that the renderer can drive, while the one returned + // from CGDisplayIDToOpenGLDisplayMask has a single bit set, representing + // that particular display. + if (requestedDisplay & supportedDisplays) + return i; + } + qCWarning(lcQpaOpenGLContext) << "Could not find virtual screen for" + << platformScreen << "with displayId" << displayId; + return 0; + }(); + auto pixelFormatAttribute = [&](NSOpenGLPixelFormatAttribute attribute) { int value = 0; - [pixelFormat getValues:&value forAttribute:attribute forVirtualScreen:0]; + [pixelFormat getValues:&value forAttribute:attribute forVirtualScreen:virtualScreen]; return value; }; -- cgit v1.2.3