diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-10-02 01:01:20 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2019-10-02 08:39:15 +0200 |
commit | 4c8814a341aace34f9a6011e9ec16048dc0f18b6 (patch) | |
tree | 3f3193c51c0883ae70de3ae3a3b225b3c7b9b8cc /src/plugins/platforms/windows | |
parent | 009d86da2d5a928865819fe44b4d1c78d455bbb9 (diff) | |
parent | 8791a8398ac232a8daab98601f1bef88bdf7638f (diff) |
Merge remote-tracking branch 'origin/5.15' into dev
Change-Id: Ideaa64d583746f1ce8265997131fb1ce3a9acbcf
Diffstat (limited to 'src/plugins/platforms/windows')
-rw-r--r-- | src/plugins/platforms/windows/qwindowsglcontext.cpp | 62 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowsglcontext.h | 3 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowsopengltester.cpp | 256 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowswindow.cpp | 12 | ||||
-rw-r--r-- | src/plugins/platforms/windows/windows.pri | 2 |
5 files changed, 65 insertions, 270 deletions
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp index 3591b2c505..d9521e7e08 100644 --- a/src/plugins/platforms/windows/qwindowsglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp @@ -891,13 +891,6 @@ QWindowsOpenGLContextFormat QWindowsOpenGLContextFormat::current() result.profile = QSurfaceFormat::CoreProfile; else if (value & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) result.profile = QSurfaceFormat::CompatibilityProfile; - if (result.version < 0x0400) - return result; - // v4.0 onwards - value = 0; - QOpenGLStaticContext::opengl32.glGetIntegerv(RESET_NOTIFICATION_STRATEGY_ARB, &value); - if (value == LOSE_CONTEXT_ON_RESET_ARB) - result.options |= QSurfaceFormat::ResetNotification; return result; } @@ -975,6 +968,7 @@ QOpenGLTemporaryContext::~QOpenGLTemporaryContext() */ #define SAMPLE_BUFFER_EXTENSION "GL_ARB_multisample" +#define ROBUSTNESS_EXTENSION "GL_ARB_robustness" QOpenGLStaticContext::QOpenGLStaticContext() : vendor(QOpenGLStaticContext::getGlString(GL_VENDOR)), @@ -995,9 +989,31 @@ QOpenGLStaticContext::QOpenGLStaticContext() : wglGetExtensionsStringARB(reinterpret_cast<WglGetExtensionsStringARB>( reinterpret_cast<QFunctionPointer>(QOpenGLStaticContext::opengl32.wglGetProcAddress("wglGetExtensionsStringARB")))) { - if (extensionNames.startsWith(SAMPLE_BUFFER_EXTENSION " ") - || extensionNames.indexOf(" " SAMPLE_BUFFER_EXTENSION " ") != -1) - extensions |= SampleBuffers; + if (defaultFormat.version < 0x0300) { + if (extensionNames.startsWith(SAMPLE_BUFFER_EXTENSION " ") + || extensionNames.indexOf(" " SAMPLE_BUFFER_EXTENSION " ") != -1) + extensions |= SampleBuffers; + if (extensionNames.startsWith(ROBUSTNESS_EXTENSION " ") + || extensionNames.indexOf(" " ROBUSTNESS_EXTENSION " ") != -1) + extensions |= Robustness; + } else { + typedef const GLubyte * (APIENTRY *glGetStringi_t)(GLenum, GLuint); + auto glGetStringi = reinterpret_cast<glGetStringi_t>( + reinterpret_cast<QFunctionPointer>(QOpenGLStaticContext::opengl32.wglGetProcAddress("glGetStringi"))); + if (glGetStringi) { + GLint n = 0; + QOpenGLStaticContext::opengl32.glGetIntegerv(GL_NUM_EXTENSIONS, &n); + for (GLint i = 0; i < n; ++i) { + const char *p = reinterpret_cast<const char *>(glGetStringi(GL_EXTENSIONS, i)); + if (p) { + if (!strcmp(p, SAMPLE_BUFFER_EXTENSION)) + extensions |= SampleBuffers; + else if (!strcmp(p, ROBUSTNESS_EXTENSION)) + extensions |= Robustness; + } + } + } + } } QByteArray QOpenGLStaticContext::getGlString(unsigned int which) @@ -1236,27 +1252,11 @@ bool QWindowsGLContext::updateObtainedParams(HDC hdc, int *obtainedSwapInterval) if (m_staticContext->wglGetSwapInternalExt && obtainedSwapInterval) *obtainedSwapInterval = m_staticContext->wglGetSwapInternalExt(); - bool hasRobustness = false; - if (m_obtainedFormat.majorVersion() < 3) { - const char *exts = reinterpret_cast<const char *>(QOpenGLStaticContext::opengl32.glGetString(GL_EXTENSIONS)); - hasRobustness = exts && strstr(exts, "GL_ARB_robustness"); - } else { - typedef const GLubyte * (APIENTRY *glGetStringi_t)(GLenum, GLuint); - auto glGetStringi = reinterpret_cast<glGetStringi_t>( - reinterpret_cast<QFunctionPointer>(QOpenGLStaticContext::opengl32.wglGetProcAddress("glGetStringi"))); - if (glGetStringi) { - GLint n = 0; - QOpenGLStaticContext::opengl32.glGetIntegerv(GL_NUM_EXTENSIONS, &n); - for (GLint i = 0; i < n; ++i) { - const char *p = reinterpret_cast<const char *>(glGetStringi(GL_EXTENSIONS, i)); - if (p && !strcmp(p, "GL_ARB_robustness")) { - hasRobustness = true; - break; - } - } - } - } - if (hasRobustness) { + if (testFlag(m_staticContext->extensions, QOpenGLStaticContext::Robustness)) { + GLint value = 0; + QOpenGLStaticContext::opengl32.glGetIntegerv(RESET_NOTIFICATION_STRATEGY_ARB, &value); + if (value == LOSE_CONTEXT_ON_RESET_ARB) + m_obtainedFormat.setOption(QSurfaceFormat::ResetNotification); m_getGraphicsResetStatus = reinterpret_cast<GlGetGraphicsResetStatusArbType>( reinterpret_cast<QFunctionPointer>(QOpenGLStaticContext::opengl32.wglGetProcAddress("glGetGraphicsResetStatusARB"))); } diff --git a/src/plugins/platforms/windows/qwindowsglcontext.h b/src/plugins/platforms/windows/qwindowsglcontext.h index e962af39c2..e5f6fefd5a 100644 --- a/src/plugins/platforms/windows/qwindowsglcontext.h +++ b/src/plugins/platforms/windows/qwindowsglcontext.h @@ -142,7 +142,8 @@ public: enum Extensions { SampleBuffers = 0x1, - sRGBCapableFramebuffer = 0x2 + sRGBCapableFramebuffer = 0x2, + Robustness = 0x4, }; typedef bool diff --git a/src/plugins/platforms/windows/qwindowsopengltester.cpp b/src/plugins/platforms/windows/qwindowsopengltester.cpp index 63ecbfe0ea..afc1991e2c 100644 --- a/src/plugins/platforms/windows/qwindowsopengltester.cpp +++ b/src/plugins/platforms/windows/qwindowsopengltester.cpp @@ -47,7 +47,6 @@ #include <QtCore/qfile.h> #include <QtCore/qfileinfo.h> #include <QtCore/qstandardpaths.h> -#include <QtCore/qlibrary.h> #include <QtCore/qlibraryinfo.h> #include <QtCore/qhash.h> @@ -58,8 +57,6 @@ #include <QtCore/qt_windows.h> #include <private/qsystemlibrary_p.h> #include <d3d9.h> -#include <d3d10.h> -#include <dxgi.h> QT_BEGIN_NAMESPACE @@ -83,259 +80,52 @@ static GpuDescription adapterIdentifierToGpuDescription(const D3DADAPTER_IDENTIF return result; } -class QGraphicsAdapterInfo +class QDirect3D9Handle { public: - Q_DISABLE_COPY_MOVE(QGraphicsAdapterInfo) + Q_DISABLE_COPY_MOVE(QDirect3D9Handle) - QGraphicsAdapterInfo(); - ~QGraphicsAdapterInfo(); + QDirect3D9Handle(); + ~QDirect3D9Handle(); - bool isValid() const; + bool isValid() const { return m_direct3D9 != nullptr; } - UINT adapterCount() const; + UINT adapterCount() const { return m_direct3D9 ? m_direct3D9->GetAdapterCount() : 0u; } bool retrieveAdapterIdentifier(UINT n, D3DADAPTER_IDENTIFIER9 *adapterIdentifier) const; private: - QSystemLibrary m_dxgilib; - IDXGIFactory1 *m_dxgiFactory1 = nullptr; - QSystemLibrary m_d3d9lib; IDirect3D9 *m_direct3D9 = nullptr; - - /* This is a value from the DXGI_ADAPTER_FLAG enum. - * However, it's not available in dxgi.h from MinGW, - * so define it here in any case. */ - enum { DXGI_ADAPTER_FLAG_SOFTWARE = 2 }; - - UINT adapterCountDXGI() const; - bool retrieveAdapterIdentifierDXGI(UINT n, D3DADAPTER_IDENTIFIER9 *adapterIdentifier) const; - - UINT adapterCountD3D9() const; - bool retrieveAdapterIdentifierD3D9(UINT n, D3DADAPTER_IDENTIFIER9 *adapterIdentifier) const; }; -QGraphicsAdapterInfo::QGraphicsAdapterInfo() : - m_dxgilib(QStringLiteral("dxgi")), +QDirect3D9Handle::QDirect3D9Handle() : m_d3d9lib(QStringLiteral("d3d9")) { - using PtrCreateDXGIFactory1 = HRESULT (WINAPI *)(REFIID, void**); + using PtrDirect3DCreate9 = IDirect3D9 *(WINAPI *)(UINT); - if (m_dxgilib.load()) { - if (auto createDXGIFactory1 = (PtrCreateDXGIFactory1)m_dxgilib.resolve("CreateDXGIFactory1")) - createDXGIFactory1(IID_PPV_ARGS(&m_dxgiFactory1)); - } - - if (!m_dxgiFactory1) { - using PtrDirect3DCreate9 = IDirect3D9 *(WINAPI *)(UINT); - - if (m_d3d9lib.load()) { - if (auto direct3DCreate9 = (PtrDirect3DCreate9)m_d3d9lib.resolve("Direct3DCreate9")) - m_direct3D9 = direct3DCreate9(D3D_SDK_VERSION); - } + if (m_d3d9lib.load()) { + if (auto direct3DCreate9 = (PtrDirect3DCreate9)m_d3d9lib.resolve("Direct3DCreate9")) + m_direct3D9 = direct3DCreate9(D3D_SDK_VERSION); } } -QGraphicsAdapterInfo::~QGraphicsAdapterInfo() +QDirect3D9Handle::~QDirect3D9Handle() { - if (m_dxgiFactory1) - m_dxgiFactory1->Release(); if (m_direct3D9) m_direct3D9->Release(); } -bool QGraphicsAdapterInfo::isValid() const -{ - return m_dxgiFactory1 != nullptr || m_direct3D9 != nullptr; -} - -UINT QGraphicsAdapterInfo::adapterCount() const -{ - if (m_dxgiFactory1) - return adapterCountDXGI(); - if (m_direct3D9) - return adapterCountD3D9(); - return 0; -} - -bool QGraphicsAdapterInfo::retrieveAdapterIdentifier(UINT n, D3DADAPTER_IDENTIFIER9 *adapterIdentifier) const -{ - if (m_dxgiFactory1) - return retrieveAdapterIdentifierDXGI(n, adapterIdentifier); - if (m_direct3D9) - return retrieveAdapterIdentifierD3D9(n, adapterIdentifier); - return false; -} - -UINT QGraphicsAdapterInfo::adapterCountDXGI() const -{ - /* DXGI doesn't have an adapterCount(), instead we have to call EnumAdapters1() - * until DXGI_ERROR_NOT_FOUND is returned. */ - UINT n = 0; - - IDXGIAdapter1 *adapter; - while (SUCCEEDED(m_dxgiFactory1->EnumAdapters1(n, &adapter))) { - adapter->Release(); - ++n; - } - - return n; -} - -// Detect whether we are running under 64-bit Windows. -static bool isWow64Process() -{ - typedef BOOL (WINAPI *IsWow64ProcessPtr)(HANDLE hProcess, PBOOL Wow64Process); - IsWow64ProcessPtr IsWow64Process = (IsWow64ProcessPtr)QLibrary::resolve( - QStringLiteral("kernel32.dll"), "IsWow64Process"); - - if (IsWow64Process) { - BOOL IsWow64 = FALSE; - if (IsWow64Process(GetCurrentProcess(), &IsWow64)) - return IsWow64; - } - return false; -} - -// Read a string value from registry -static QString regGetString(HKEY key, const wchar_t* valueName) -{ - QVarLengthArray<wchar_t, MAX_PATH> buf (MAX_PATH); - LRESULT res; - DWORD bufSize = buf.size() * sizeof(wchar_t); - res = RegGetValue(key, nullptr, valueName, - RRF_RT_REG_SZ | RRF_RT_REG_MULTI_SZ, nullptr, - buf.data(), &bufSize); - if (res == ERROR_MORE_DATA) { - buf.resize(bufSize / sizeof(wchar_t)); - bufSize = buf.size() * sizeof(wchar_t); - res = RegGetValue(key, nullptr, valueName, - RRF_RT_REG_SZ | RRF_RT_REG_MULTI_SZ, nullptr, - buf.data(), &bufSize); - } - /* In case of REG_MULTI_SZ, this returns just the first string, - * but that is sufficient for our purposes. */ - if (res == ERROR_SUCCESS) - return QString::fromWCharArray(buf.data()); - return QString(); -} - -// Read driver name given a DeviceKey -static QString retrieveDriverName(const wchar_t *driverKey) -{ - /* Kernel-style prefix, maps to HKLM - * (see https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/registry-key-object-routines) */ - static const wchar_t prefixMappingHKLM[] = L"\\Registry\\Machine\\"; - const size_t prefixMappingHKLMLen = wcslen(prefixMappingHKLM); - if (wcsnicmp(driverKey, prefixMappingHKLM, prefixMappingHKLMLen) != 0) - return QString(); - - driverKey += prefixMappingHKLMLen; - QString driverPath; - HKEY key; - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, driverKey, 0, KEY_READ | KEY_WOW64_64KEY, &key) == ERROR_SUCCESS) { - const wchar_t *valueName = - isWow64Process() ? L"UserModeDriverNameWow" : L"UserModeDriverName"; - driverPath = regGetString(key, valueName); - RegCloseKey(key); - } - if (!driverPath.isEmpty()) { - int fileNameSep = driverPath.lastIndexOf(QLatin1Char('\\')); - if (fileNameSep >= 0) - driverPath = driverPath.mid(fileNameSep + 1); - return driverPath; - } - return QString(); -} - -// Retrieve driver name for a display device from registry. -static QString driverNameForDevice(const wchar_t *displayDevice) -{ - QString driverName; - DISPLAY_DEVICE dd; - memset(&dd, 0, sizeof(dd)); - dd.cb = sizeof(dd); - for (int dev = 0; EnumDisplayDevices(nullptr, dev, &dd, 0); ++dev) { - if (wcsicmp(displayDevice, dd.DeviceName) == 0) { - // DeviceKey is documented as "internal", but it's a registry key in kernel format - driverName = retrieveDriverName(dd.DeviceKey); - break; - } - } - if (driverName.isEmpty()) { - /* Fall back to driver name from EnumDisplaySettings. - * This is only a fallback as on Windows 10 this just returns an device-independent - * name. OTOH, it's possible to recognize RDP connections from the driver name. */ - DEVMODE devMode; - if (EnumDisplaySettings(displayDevice, ENUM_CURRENT_SETTINGS, &devMode)) - driverName = QString::fromWCharArray(devMode.dmDeviceName); - } - return driverName; -} - -bool QGraphicsAdapterInfo::retrieveAdapterIdentifierDXGI(UINT n, D3DADAPTER_IDENTIFIER9 *adapterIdentifier) const -{ - IDXGIAdapter1 *adapter; - if (FAILED(m_dxgiFactory1->EnumAdapters1(n, &adapter))) - return false; - - bool result = false; - - DXGI_ADAPTER_DESC1 adapterDesc; - if (SUCCEEDED(adapter->GetDesc1(&adapterDesc))) { - if ((adapterDesc.VendorId != 0) && (adapterDesc.DeviceId != 0) // Don't use adapter description of Software Devices - && ((adapterDesc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) == 0)) { - memset(adapterIdentifier, 0, sizeof(*adapterIdentifier)); - WideCharToMultiByte(1252, 0, adapterDesc.Description, -1, - adapterIdentifier->Description, - sizeof(adapterIdentifier->Description), nullptr, nullptr); - adapterIdentifier->Description[sizeof(adapterIdentifier->Description) - 1] = 0; - adapterIdentifier->VendorId = adapterDesc.VendorId; - adapterIdentifier->DeviceId = adapterDesc.DeviceId; - adapterIdentifier->SubSysId = adapterDesc.SubSysId; - adapterIdentifier->Revision = adapterDesc.Revision; - - LARGE_INTEGER umdVersion; - if (SUCCEEDED(adapter->CheckInterfaceSupport(__uuidof(ID3D10Device), &umdVersion))) { - adapterIdentifier->DriverVersion = umdVersion; - result = true; - } - - /* DXGI doesn't expose the driver name, but we can get it from the registry. - * But we need a device name to follow. */ - IDXGIOutput *output = nullptr; - if (SUCCEEDED(adapter->EnumOutputs (0, &output))) { - DXGI_OUTPUT_DESC outputDesc; - if (SUCCEEDED(output->GetDesc (&outputDesc))) { - QString driverName = driverNameForDevice(outputDesc.DeviceName); - qstrncpy(adapterIdentifier->Driver, driverName.toLatin1().constData(), - sizeof(adapterIdentifier->Driver)); - } - output->Release(); - } - } - } - - adapter->Release(); - - return result; -} - -UINT QGraphicsAdapterInfo::adapterCountD3D9() const -{ - return m_direct3D9->GetAdapterCount(); -} - -bool QGraphicsAdapterInfo::retrieveAdapterIdentifierD3D9(UINT n, D3DADAPTER_IDENTIFIER9 *adapterIdentifier) const +bool QDirect3D9Handle::retrieveAdapterIdentifier(UINT n, D3DADAPTER_IDENTIFIER9 *adapterIdentifier) const { - return SUCCEEDED(m_direct3D9->GetAdapterIdentifier(n, 0, adapterIdentifier)); + return m_direct3D9 + && SUCCEEDED(m_direct3D9->GetAdapterIdentifier(n, 0, adapterIdentifier)); } GpuDescription GpuDescription::detect() { GpuDescription result; - QGraphicsAdapterInfo adapterInfo; - if (!adapterInfo.isValid()) + QDirect3D9Handle direct3D9; + if (!direct3D9.isValid()) return result; D3DADAPTER_IDENTIFIER9 adapterIdentifier; @@ -346,7 +136,7 @@ GpuDescription GpuDescription::detect() // and D3D uses by default. Therefore querying any additional adapters is // futile and not useful for our purposes in general, except for // identifying a few special cases later on. - if (adapterInfo.retrieveAdapterIdentifier(0, &adapterIdentifier)) { + if (direct3D9.retrieveAdapterIdentifier(0, &adapterIdentifier)) { result = adapterIdentifierToGpuDescription(adapterIdentifier); isAMD = result.vendorId == VENDOR_ID_AMD; } @@ -355,9 +145,9 @@ GpuDescription GpuDescription::detect() // when starting apps on a screen connected to the Intel card) by looking // for a default AMD adapter and an additional non-AMD one. if (isAMD) { - const UINT adapterCount = adapterInfo.adapterCount(); + const UINT adapterCount = direct3D9.adapterCount(); for (UINT adp = 1; adp < adapterCount; ++adp) { - if (adapterInfo.retrieveAdapterIdentifier(adp, &adapterIdentifier) + if (direct3D9.retrieveAdapterIdentifier(adp, &adapterIdentifier) && adapterIdentifier.VendorId != VENDOR_ID_AMD) { // Bingo. Now figure out the display for the AMD card. DISPLAY_DEVICE dd; @@ -382,11 +172,11 @@ GpuDescription GpuDescription::detect() QVector<GpuDescription> GpuDescription::detectAll() { QVector<GpuDescription> result; - QGraphicsAdapterInfo adapterInfo; - if (const UINT adapterCount = adapterInfo.adapterCount()) { + QDirect3D9Handle direct3D9; + if (const UINT adapterCount = direct3D9.adapterCount()) { for (UINT adp = 0; adp < adapterCount; ++adp) { D3DADAPTER_IDENTIFIER9 adapterIdentifier; - if (adapterInfo.retrieveAdapterIdentifier(adp, &adapterIdentifier)) + if (direct3D9.retrieveAdapterIdentifier(adp, &adapterIdentifier)) result.append(adapterIdentifierToGpuDescription(adapterIdentifier)); } } diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 1196190b81..5c13bd9650 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -2697,10 +2697,16 @@ bool QWindowsWindow::handleNonClientHitTest(const QPoint &globalPos, LRESULT *re return true; } if (localPos.y() < 0) { - const int topResizeBarPos = -frameMargins().top(); - if (localPos.y() >= topResizeBarPos) + // We want to return HTCAPTION/true only over the outer sizing frame, not the entire title bar, + // otherwise the title bar buttons (close, etc.) become unresponsive on Windows 7 (QTBUG-78262). + // However, neither frameMargins() nor GetSystemMetrics(SM_CYSIZEFRAME), etc., give the correct + // sizing frame height in all Windows versions/scales. This empirical constant seems to work, though. + const int sizingHeight = 9; + const int topResizeBarPos = sizingHeight - frameMargins().top(); + if (localPos.y() < topResizeBarPos) { *result = HTCAPTION; // Extend caption over top resize bar, let's user move the window. - return true; + return true; + } } } if (fixedWidth && (localPos.x() < 0 || localPos.x() >= size.width())) { diff --git a/src/plugins/platforms/windows/windows.pri b/src/plugins/platforms/windows/windows.pri index 7de6369541..95ba961df1 100644 --- a/src/plugins/platforms/windows/windows.pri +++ b/src/plugins/platforms/windows/windows.pri @@ -12,8 +12,6 @@ LIBS += -lshlwapi -lwtsapi32 QMAKE_USE_PRIVATE += \ advapi32 \ d3d9/nolink \ - d3d11/nolink \ - dxgi/nolink \ ole32 \ shell32 \ user32 \ |