diff options
Diffstat (limited to 'src/plugins/platforms/windows')
16 files changed, 267 insertions, 177 deletions
diff --git a/src/plugins/platforms/windows/openglblacklists.qrc b/src/plugins/platforms/windows/openglblacklists.qrc new file mode 100644 index 0000000000..9f0c186c21 --- /dev/null +++ b/src/plugins/platforms/windows/openglblacklists.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/qt-project.org/windows/openglblacklists"> + <file alias="default.json">openglblacklists/default.json</file> + </qresource> +</RCC> diff --git a/src/plugins/platforms/windows/openglblacklists/default.json b/src/plugins/platforms/windows/openglblacklists/default.json new file mode 100644 index 0000000000..0217b79ecf --- /dev/null +++ b/src/plugins/platforms/windows/openglblacklists/default.json @@ -0,0 +1,18 @@ +{ + "name": "Qt built-in GPU driver blacklist", + "version": "5.5", + "entries": [ + { + "id": 1, + "description": "Desktop OpenGL is unreliable on Intel HD3000/GMA (QTBUG-43263, QTBUG-42240)", + "vendor_id": "0x8086", + "device_id": [ "0x0A16" ], + "os": { + "type": "win" + }, + "features": [ + "disable_desktopgl" + ] + } + ] +} diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index ebd41d482b..fa355f6201 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -173,7 +173,7 @@ static inline QWindowsSessionManager *platformSessionManager() { QWindowsUser32DLL::QWindowsUser32DLL() : setLayeredWindowAttributes(0), updateLayeredWindow(0), updateLayeredWindowIndirect(0), - isHungAppWindow(0), + isHungAppWindow(0), isTouchWindow(0), registerTouchWindow(0), unregisterTouchWindow(0), getTouchInputInfo(0), closeTouchInputHandle(0), setProcessDPIAware(0), addClipboardFormatListener(0), removeClipboardFormatListener(0) @@ -202,11 +202,12 @@ void QWindowsUser32DLL::init() bool QWindowsUser32DLL::initTouch() { QSystemLibrary library(QStringLiteral("user32")); + isTouchWindow = (IsTouchWindow)(library.resolve("IsTouchWindow")); registerTouchWindow = (RegisterTouchWindow)(library.resolve("RegisterTouchWindow")); unregisterTouchWindow = (UnregisterTouchWindow)(library.resolve("UnregisterTouchWindow")); getTouchInputInfo = (GetTouchInputInfo)(library.resolve("GetTouchInputInfo")); closeTouchInputHandle = (CloseTouchInputHandle)(library.resolve("CloseTouchInputHandle")); - return registerTouchWindow && unregisterTouchWindow && getTouchInputInfo && closeTouchInputHandle; + return isTouchWindow && registerTouchWindow && unregisterTouchWindow && getTouchInputInfo && closeTouchInputHandle; } /*! diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h index 870a42946d..81f4a36433 100644 --- a/src/plugins/platforms/windows/qwindowscontext.h +++ b/src/plugins/platforms/windows/qwindowscontext.h @@ -76,6 +76,7 @@ struct QWindowsUser32DLL inline void init(); inline bool initTouch(); + typedef BOOL (WINAPI *IsTouchWindow)(HWND, PULONG); typedef BOOL (WINAPI *RegisterTouchWindow)(HWND, ULONG); typedef BOOL (WINAPI *UnregisterTouchWindow)(HWND); typedef BOOL (WINAPI *GetTouchInputInfo)(HANDLE, UINT, PVOID, int); @@ -99,6 +100,7 @@ struct QWindowsUser32DLL IsHungAppWindow isHungAppWindow; // Touch functions from Windows 7 onwards (also for use with Q_CC_MSVC). + IsTouchWindow isTouchWindow; RegisterTouchWindow registerTouchWindow; UnregisterTouchWindow unregisterTouchWindow; GetTouchInputInfo getTouchInputInfo; diff --git a/src/plugins/platforms/windows/qwindowseglcontext.cpp b/src/plugins/platforms/windows/qwindowseglcontext.cpp index 74efd49217..7db6abd8ef 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowseglcontext.cpp @@ -416,12 +416,15 @@ QWindowsOpenGLContext *QWindowsEGLStaticContext::createContext(QOpenGLContext *c return new QWindowsEGLContext(this, context->format(), context->shareHandle()); } -void *QWindowsEGLStaticContext::createWindowSurface(void *nativeWindow, void *nativeConfig) +void *QWindowsEGLStaticContext::createWindowSurface(void *nativeWindow, void *nativeConfig, int *err) { + *err = 0; EGLSurface surface = libEGL.eglCreateWindowSurface(m_display, (EGLConfig) nativeConfig, (EGLNativeWindowType) nativeWindow, 0); - if (surface == EGL_NO_SURFACE) - qWarning("%s: Could not create the EGL window surface: 0x%x\n", Q_FUNC_INFO, libEGL.eglGetError()); + if (surface == EGL_NO_SURFACE) { + *err = libEGL.eglGetError(); + qWarning("%s: Could not create the EGL window surface: 0x%x\n", Q_FUNC_INFO, *err); + } return surface; } @@ -578,8 +581,15 @@ bool QWindowsEGLContext::makeCurrent(QPlatformSurface *surface) QWindowsWindow *window = static_cast<QWindowsWindow *>(surface); window->aboutToMakeCurrent(); - EGLSurface eglSurface = static_cast<EGLSurface>(window->surface(m_eglConfig)); - Q_ASSERT(eglSurface); + int err = 0; + EGLSurface eglSurface = static_cast<EGLSurface>(window->surface(m_eglConfig, &err)); + if (eglSurface == EGL_NO_SURFACE) { + if (err == EGL_CONTEXT_LOST) { + m_eglContext = EGL_NO_CONTEXT; + qCDebug(lcQpaGl) << "Got EGL context lost in createWindowSurface() for context" << this; + } + return false; + } // shortcut: on some GPUs, eglMakeCurrent is not a cheap operation if (QWindowsEGLStaticContext::libEGL.eglGetCurrentContext() == m_eglContext && @@ -597,7 +607,7 @@ bool QWindowsEGLContext::makeCurrent(QPlatformSurface *surface) QWindowsEGLStaticContext::libEGL.eglSwapInterval(m_staticContext->display(), m_swapInterval); } } else { - int err = QWindowsEGLStaticContext::libEGL.eglGetError(); + err = QWindowsEGLStaticContext::libEGL.eglGetError(); // EGL_CONTEXT_LOST (loss of the D3D device) is not necessarily fatal. // Qt Quick is able to recover for example. if (err == EGL_CONTEXT_LOST) { @@ -625,8 +635,15 @@ void QWindowsEGLContext::swapBuffers(QPlatformSurface *surface) { QWindowsEGLStaticContext::libEGL.eglBindAPI(m_api); QWindowsWindow *window = static_cast<QWindowsWindow *>(surface); - EGLSurface eglSurface = static_cast<EGLSurface>(window->surface(m_eglConfig)); - Q_ASSERT(eglSurface); + int err = 0; + EGLSurface eglSurface = static_cast<EGLSurface>(window->surface(m_eglConfig, &err)); + if (eglSurface == EGL_NO_SURFACE) { + if (err == EGL_CONTEXT_LOST) { + m_eglContext = EGL_NO_CONTEXT; + qCDebug(lcQpaGl) << "Got EGL context lost in createWindowSurface() for context" << this; + } + return; + } bool ok = QWindowsEGLStaticContext::libEGL.eglSwapBuffers(m_eglDisplay, eglSurface); if (!ok) diff --git a/src/plugins/platforms/windows/qwindowseglcontext.h b/src/plugins/platforms/windows/qwindowseglcontext.h index 55f58fac5f..2b249348c3 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.h +++ b/src/plugins/platforms/windows/qwindowseglcontext.h @@ -260,7 +260,7 @@ public: void *moduleHandle() const { return libGLESv2.moduleHandle(); } QOpenGLContext::OpenGLModuleType moduleType() const { return QOpenGLContext::LibGLES; } - void *createWindowSurface(void *nativeWindow, void *nativeConfig) Q_DECL_OVERRIDE; + void *createWindowSurface(void *nativeWindow, void *nativeConfig, int *err) Q_DECL_OVERRIDE; void destroyWindowSurface(void *nativeSurface) Q_DECL_OVERRIDE; QSurfaceFormat formatFromConfig(EGLDisplay display, EGLConfig config, const QSurfaceFormat &referenceFormat); diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp index d1ea8a798f..ad75a0bd54 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp @@ -336,7 +336,8 @@ static bool addFontToDatabase(const QString &faceName, uchar charSet, const TEXTMETRIC *textmetric, const FONTSIGNATURE *signature, - int type) + int type, + bool registerAlias) { // the "@family" fonts are just the same as "family". Ignore them. if (faceName.isEmpty() || faceName.at(0) == QLatin1Char('@') || faceName.startsWith(QLatin1String("WST_"))) @@ -373,7 +374,7 @@ static bool addFontToDatabase(const QString &faceName, #endif QString englishName; - if (ttf && localizedName(faceName)) + if (registerAlias & ttf && localizedName(faceName)) englishName = getEnglishName(faceName); QSupportedWritingSystems writingSystems; @@ -467,64 +468,23 @@ static QByteArray getFntTable(HFONT hfont, uint tag) #endif static int QT_WIN_CALLBACK storeFont(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *textmetric, - int type, LPARAM namesSetIn) + int type, LPARAM) { - typedef QSet<QString> StringSet; const QString faceName = QString::fromWCharArray(f->elfLogFont.lfFaceName); const QString fullName = QString::fromWCharArray(f->elfFullName); const uchar charSet = f->elfLogFont.lfCharSet; -#ifndef Q_OS_WINCE const FONTSIGNATURE signature = textmetric->ntmFontSig; -#else - FONTSIGNATURE signature; - QByteArray table; - - if (type & TRUETYPE_FONTTYPE) { - HFONT hfont = CreateFontIndirect(&f->elfLogFont); - table = getFntTable(hfont, MAKE_TAG('O', 'S', '/', '2')); - DeleteObject((HGDIOBJ)hfont); - } - - if (table.length() >= 86) { - // See also qfontdatabase_mac.cpp, offsets taken from OS/2 table in the TrueType spec - uchar *tableData = reinterpret_cast<uchar *>(table.data()); - - signature.fsUsb[0] = qFromBigEndian<quint32>(tableData + 42); - signature.fsUsb[1] = qFromBigEndian<quint32>(tableData + 46); - signature.fsUsb[2] = qFromBigEndian<quint32>(tableData + 50); - signature.fsUsb[3] = qFromBigEndian<quint32>(tableData + 54); - - signature.fsCsb[0] = qFromBigEndian<quint32>(tableData + 78); - signature.fsCsb[1] = qFromBigEndian<quint32>(tableData + 82); - } else { - memset(&signature, 0, sizeof(signature)); - } -#endif - // NEWTEXTMETRICEX is a NEWTEXTMETRIC, which according to the documentation is // identical to a TEXTMETRIC except for the last four members, which we don't use // anyway - if (addFontToDatabase(faceName, fullName, - charSet, (TEXTMETRIC *)textmetric, &signature, type)) { - reinterpret_cast<StringSet *>(namesSetIn)->insert(faceName + QStringLiteral("::") + fullName); - } + addFontToDatabase(faceName, fullName, charSet, (TEXTMETRIC *)textmetric, &signature, type, false); // keep on enumerating return 1; } -void QWindowsFontDatabaseFT::populateFontDatabase() -{ - m_families.clear(); - populate(); // Called multiple times. - // Work around EnumFontFamiliesEx() not listing the system font, see below. - const QString sysFontFamily = QGuiApplication::font().family(); - if (!m_families.contains(sysFontFamily)) - populate(sysFontFamily); -} - /*! \brief Populate font database using EnumFontFamiliesEx(). @@ -533,29 +493,157 @@ void QWindowsFontDatabaseFT::populateFontDatabase() are only found when specifying the name explicitly. */ -void QWindowsFontDatabaseFT::populate(const QString &family) - { - - qCDebug(lcQpaFonts) << __FUNCTION__ << m_families.size() << family; - +void QWindowsFontDatabaseFT::populateFamily(const QString &familyName) +{ + qCDebug(lcQpaFonts) << familyName; + if (familyName.size() >= LF_FACESIZE) { + qCWarning(lcQpaFonts) << "Unable to enumerate family '" << familyName << '\''; + return; + } HDC dummy = GetDC(0); LOGFONT lf; lf.lfCharSet = DEFAULT_CHARSET; - if (family.size() >= LF_FACESIZE) { - qWarning("%s: Unable to enumerate family '%s'.", - __FUNCTION__, qPrintable(family)); - return; + familyName.toWCharArray(lf.lfFaceName); + lf.lfFaceName[familyName.size()] = 0; + lf.lfPitchAndFamily = 0; + EnumFontFamiliesEx(dummy, &lf, (FONTENUMPROC)storeFont, 0, 0); + ReleaseDC(0, dummy); +} + +namespace { +// Context for enumerating system fonts, records whether the default font has been +// encountered, which is normally not enumerated. +struct PopulateFamiliesContext +{ + PopulateFamiliesContext(const QString &f) : systemDefaultFont(f), seenSystemDefaultFont(false) {} + + QString systemDefaultFont; + bool seenSystemDefaultFont; +}; +} // namespace + +#ifndef Q_OS_WINCE + +// Delayed population of font families + +static int QT_WIN_CALLBACK populateFontFamilies(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *tm, int, LPARAM lparam) +{ + // the "@family" fonts are just the same as "family". Ignore them. + const wchar_t *faceNameW = f->elfLogFont.lfFaceName; + if (faceNameW[0] && faceNameW[0] != L'@' && wcsncmp(faceNameW, L"WST_", 4)) { + // Register only font families for which a font file exists for delayed population + const QString faceName = QString::fromWCharArray(faceNameW); + const FontKey *key = findFontKey(faceName); + if (!key) { + key = findFontKey(QString::fromWCharArray(f->elfFullName)); + if (!key && (tm->ntmTm.tmPitchAndFamily & TMPF_TRUETYPE) && localizedName(faceName)) + key = findFontKey(getEnglishName(faceName)); + } + if (key) { + QPlatformFontDatabase::registerFontFamily(faceName); + PopulateFamiliesContext *context = reinterpret_cast<PopulateFamiliesContext *>(lparam); + if (!context->seenSystemDefaultFont && faceName == context->systemDefaultFont) + context->seenSystemDefaultFont = true; + + // Register current font's english name as alias + const bool ttf = (tm->ntmTm.tmPitchAndFamily & TMPF_TRUETYPE); + if (ttf && localizedName(faceName)) { + const QString englishName = getEnglishName(faceName); + if (!englishName.isEmpty()) { + QPlatformFontDatabase::registerAliasToFontFamily(faceName, englishName); + // Check whether the system default font name is an alias of the current font family name, + // as on Chinese Windows, where the system font "SimSun" is an alias to a font registered under a local name + if (!context->seenSystemDefaultFont && englishName == context->systemDefaultFont) + context->seenSystemDefaultFont = true; + } + } + } } + return 1; // continue +} - wmemcpy(lf.lfFaceName, reinterpret_cast<const wchar_t*>(family.utf16()), - family.size() + 1); +void QWindowsFontDatabaseFT::populateFontDatabase() +{ + HDC dummy = GetDC(0); + LOGFONT lf; + lf.lfCharSet = DEFAULT_CHARSET; + lf.lfFaceName[0] = 0; lf.lfPitchAndFamily = 0; + PopulateFamiliesContext context(QWindowsFontDatabase::systemDefaultFont().family()); + EnumFontFamiliesEx(dummy, &lf, (FONTENUMPROC)populateFontFamilies, reinterpret_cast<LPARAM>(&context), 0); + ReleaseDC(0, dummy); + // Work around EnumFontFamiliesEx() not listing the system font + if (!context.seenSystemDefaultFont) + QPlatformFontDatabase::registerFontFamily(context.systemDefaultFont); +} + +#else // !Q_OS_WINCE + +// Non-delayed population of fonts (Windows CE). + +static int QT_WIN_CALLBACK populateFontCe(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *textmetric, + int type, LPARAM lparam) +{ + // the "@family" fonts are just the same as "family". Ignore them. + const wchar_t *faceNameW = f->elfLogFont.lfFaceName; + if (faceNameW[0] && faceNameW[0] != L'@' && wcsncmp(faceNameW, L"WST_", 4)) { + const uchar charSet = f->elfLogFont.lfCharSet; + + FONTSIGNATURE signature; + QByteArray table; + + if (type & TRUETYPE_FONTTYPE) { + HFONT hfont = CreateFontIndirect(&f->elfLogFont); + table = getFntTable(hfont, MAKE_TAG('O', 'S', '/', '2')); + DeleteObject((HGDIOBJ)hfont); + } + + if (table.length() >= 86) { + // See also qfontdatabase_mac.cpp, offsets taken from OS/2 table in the TrueType spec + uchar *tableData = reinterpret_cast<uchar *>(table.data()); + + signature.fsUsb[0] = qFromBigEndian<quint32>(tableData + 42); + signature.fsUsb[1] = qFromBigEndian<quint32>(tableData + 46); + signature.fsUsb[2] = qFromBigEndian<quint32>(tableData + 50); + signature.fsUsb[3] = qFromBigEndian<quint32>(tableData + 54); + + signature.fsCsb[0] = qFromBigEndian<quint32>(tableData + 78); + signature.fsCsb[1] = qFromBigEndian<quint32>(tableData + 82); + } else { + memset(&signature, 0, sizeof(signature)); + } - EnumFontFamiliesEx(dummy, &lf, (FONTENUMPROC)storeFont, - (LPARAM)&m_families, 0); + // NEWTEXTMETRICEX is a NEWTEXTMETRIC, which according to the documentation is + // identical to a TEXTMETRIC except for the last four members, which we don't use + // anyway + const QString faceName = QString::fromWCharArray(f->elfLogFont.lfFaceName); + if (addFontToDatabase(faceName, QString::fromWCharArray(f->elfFullName), + charSet, (TEXTMETRIC *)textmetric, &signature, type, true)) { + PopulateFamiliesContext *context = reinterpret_cast<PopulateFamiliesContext *>(lparam); + if (!context->seenSystemDefaultFont && faceName == context->systemDefaultFont) + context->seenSystemDefaultFont = true; + } + } + // keep on enumerating + return 1; +} + +void QWindowsFontDatabaseFT::populateFontDatabase() +{ + LOGFONT lf; + lf.lfCharSet = DEFAULT_CHARSET; + HDC dummy = GetDC(0); + lf.lfFaceName[0] = 0; + lf.lfPitchAndFamily = 0; + PopulateFamiliesContext context(QWindowsFontDatabase::systemDefaultFont().family()); + EnumFontFamiliesEx(dummy, &lf, (FONTENUMPROC)populateFontCe, reinterpret_cast<LPARAM>(&context), 0); ReleaseDC(0, dummy); + // Work around EnumFontFamiliesEx() not listing the system font, see below. + if (!context.seenSystemDefaultFont) + populateFamily(context.systemDefaultFont); } +#endif // Q_OS_WINCE QFontEngine * QWindowsFontDatabaseFT::fontEngine(const QFontDef &fontDef, void *handle) { @@ -592,7 +680,7 @@ QStringList QWindowsFontDatabaseFT::fallbacksForFamily(const QString &family, QF result.append(QWindowsFontDatabase::extraTryFontsForFamily(family)); qCDebug(lcQpaFonts) << __FUNCTION__ << family << style << styleHint - << script << result << m_families; + << script << result; return result; } diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h index 7552458a9f..ad5c005ffa 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h +++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h @@ -44,6 +44,7 @@ class QWindowsFontDatabaseFT : public QBasicFontDatabase { public: void populateFontDatabase(); + void populateFamily(const QString &familyName) Q_DECL_OVERRIDE; QFontEngine *fontEngine(const QFontDef &fontDef, void *handle); QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference); @@ -51,11 +52,6 @@ public: QString fontDir() const Q_DECL_OVERRIDE; QFont defaultFont() const Q_DECL_OVERRIDE; - -private: - void populate(const QString &family = QString()); - - QSet<QString> m_families; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp index ca28b822e4..c25b90e98c 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.cpp +++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp @@ -194,10 +194,10 @@ void QWindowsFontEngine::getCMap() _faceId.index = 0; if(cmap) { OUTLINETEXTMETRIC *otm = getOutlineTextMetric(hdc); - designToDevice = QFixed((int)otm->otmEMSquare)/int(otm->otmTextMetrics.tmHeight); + designToDevice = QFixed((int)otm->otmEMSquare)/QFixed::fromReal(fontDef.pixelSize); unitsPerEm = otm->otmEMSquare; x_height = (int)otm->otmsXHeight; - loadKerningPairs(designToDevice); + loadKerningPairs(QFixed((int)otm->otmEMSquare)/int(otm->otmTextMetrics.tmHeight)); _faceId.filename = QFile::encodeName(QString::fromWCharArray((wchar_t *)((char *)otm + (quintptr)otm->otmpFullName))); lineWidth = otm->otmsUnderscoreSize; fsType = otm->otmfsType; @@ -361,7 +361,7 @@ glyph_t QWindowsFontEngine::glyphIndex(uint ucs4) const HGDIOBJ QWindowsFontEngine::selectDesignFont() const { LOGFONT f = m_logfont; - f.lfHeight = unitsPerEm; + f.lfHeight = -unitsPerEm; f.lfWidth = 0; HFONT designFont = CreateFontIndirect(&f); return SelectObject(m_fontEngineData->hdc, designFont); diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index 9fd18a1ef4..1041ecf44d 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -79,9 +79,7 @@ # include "qwindowsglcontext.h" #endif -#ifndef Q_OS_WINCE -# include "qwindowsopengltester.h" -#endif +#include "qwindowsopengltester.h" QT_BEGIN_NAMESPACE @@ -209,6 +207,10 @@ QWindowsIntegrationPrivate::QWindowsIntegrationPrivate(const QStringList ¶mL : m_options(0) , m_fontDatabase(0) { +#ifndef Q_OS_WINCE + Q_INIT_RESOURCE(openglblacklists); +#endif + static bool dpiAwarenessSet = false; int tabletAbsoluteRange = -1; // Default to per-monitor awareness to avoid being scaled when monitors with different DPI diff --git a/src/plugins/platforms/windows/qwindowsopenglcontext.h b/src/plugins/platforms/windows/qwindowsopenglcontext.h index 8ebcb83a08..2c52c58829 100644 --- a/src/plugins/platforms/windows/qwindowsopenglcontext.h +++ b/src/plugins/platforms/windows/qwindowsopenglcontext.h @@ -56,7 +56,7 @@ public: // If the windowing system interface needs explicitly created window surfaces (like EGL), // reimplement these. - virtual void *createWindowSurface(void * /*nativeWindow*/, void * /*nativeConfig*/) { return 0; } + virtual void *createWindowSurface(void * /*nativeWindow*/, void * /*nativeConfig*/, int * /*err*/) { return 0; } virtual void destroyWindowSurface(void * /*nativeSurface*/) { } private: diff --git a/src/plugins/platforms/windows/qwindowsopengltester.cpp b/src/plugins/platforms/windows/qwindowsopengltester.cpp index ba4c95544e..67548a0836 100644 --- a/src/plugins/platforms/windows/qwindowsopengltester.cpp +++ b/src/plugins/platforms/windows/qwindowsopengltester.cpp @@ -42,14 +42,16 @@ #include <QtCore/QFileInfo> #include <QtCore/QStandardPaths> #include <QtCore/QLibraryInfo> +#include <QtCore/QHash> +#ifndef QT_NO_OPENGL #include <private/qopengl_p.h> +#endif #ifndef Q_OS_WINCE # include <QtCore/qt_windows.h> # include <private/qsystemlibrary_p.h> # include <d3d9.h> -# include <GL/gl.h> #endif QT_BEGIN_NAMESPACE @@ -206,56 +208,62 @@ static inline QString resolveBugListFile(const QString &fileName) return QStandardPaths::locate(QStandardPaths::ConfigLocation, fileName); } -static void readDriverBugList(const GpuDescription &gpu, - QWindowsOpenGLTester::Renderers *result) +typedef QHash<QOpenGLConfig::Gpu, QWindowsOpenGLTester::Renderers> SupportedRenderersCache; +Q_GLOBAL_STATIC(SupportedRenderersCache, supportedRenderersCache) + +#endif // !Q_OS_WINCE + +QWindowsOpenGLTester::Renderers QWindowsOpenGLTester::detectSupportedRenderers(const GpuDescription &gpu, bool glesOnly) { - const char bugListFileVar[] = "QT_OPENGL_BUGLIST"; - if (!qEnvironmentVariableIsSet(bugListFileVar)) - return; - const QString fileName = resolveBugListFile(QFile::decodeName(qgetenv(bugListFileVar))); - if (fileName.isEmpty()) - return; + Q_UNUSED(gpu) +#ifndef Q_OS_WINCE QOpenGLConfig::Gpu qgpu; qgpu.deviceId = gpu.deviceId; qgpu.vendorId = gpu.vendorId; qgpu.driverVersion = gpu.driverVersion; - const QSet<QString> features = QOpenGLConfig::gpuFeatures(qgpu, fileName); + SupportedRenderersCache *srCache = supportedRenderersCache(); + SupportedRenderersCache::const_iterator it = srCache->find(qgpu); + if (it != srCache->cend()) + return *it; + + QWindowsOpenGLTester::Renderers result(QWindowsOpenGLTester::AngleRendererD3d11 + | QWindowsOpenGLTester::AngleRendererD3d9 + | QWindowsOpenGLTester::AngleRendererD3d11Warp + | QWindowsOpenGLTester::SoftwareRasterizer); + + if (!glesOnly && testDesktopGL()) + result |= QWindowsOpenGLTester::DesktopGl; + + QSet<QString> features; + const char bugListFileVar[] = "QT_OPENGL_BUGLIST"; + if (qEnvironmentVariableIsSet(bugListFileVar)) { + const QString fileName = resolveBugListFile(QFile::decodeName(qgetenv(bugListFileVar))); + if (!fileName.isEmpty()) + features = QOpenGLConfig::gpuFeatures(qgpu, fileName); + } else { + features = QOpenGLConfig::gpuFeatures(qgpu, QStringLiteral(":/qt-project.org/windows/openglblacklists/default.json")); + } + qCDebug(lcQpaGl) << "GPU features:" << features; + if (features.contains(QStringLiteral("disable_desktopgl"))) { // Qt-specific qCWarning(lcQpaGl) << "Disabling Desktop GL: " << gpu; - *result &= ~QWindowsOpenGLTester::DesktopGl; + result &= ~QWindowsOpenGLTester::DesktopGl; } if (features.contains(QStringLiteral("disable_angle"))) { // Qt-specific keyword qCWarning(lcQpaGl) << "Disabling ANGLE: " << gpu; - *result &= ~QWindowsOpenGLTester::GlesMask; + result &= ~QWindowsOpenGLTester::GlesMask; } else { if (features.contains(QStringLiteral("disable_d3d11"))) { // standard keyword qCWarning(lcQpaGl) << "Disabling D3D11: " << gpu; - *result &= ~QWindowsOpenGLTester::AngleRendererD3d11; + result &= ~QWindowsOpenGLTester::AngleRendererD3d11; } if (features.contains(QStringLiteral("disable_d3d9"))) { // Qt-specific qCWarning(lcQpaGl) << "Disabling D3D9: " << gpu; - *result &= ~QWindowsOpenGLTester::AngleRendererD3d9; + result &= ~QWindowsOpenGLTester::AngleRendererD3d9; } } -} -#endif // !Q_OS_WINCE - -static inline QWindowsOpenGLTester::Renderers - detectSupportedRenderers(const GpuDescription &gpu, bool glesOnly) -{ - Q_UNUSED(gpu) -#ifndef Q_OS_WINCE - // Add checks for card types with known issues here. - QWindowsOpenGLTester::Renderers result(QWindowsOpenGLTester::AngleRendererD3d11 - | QWindowsOpenGLTester::AngleRendererD3d9 - | QWindowsOpenGLTester::AngleRendererD3d11Warp - | QWindowsOpenGLTester::SoftwareRasterizer); - - if (!glesOnly && QWindowsOpenGLTester::testDesktopGL()) - result |= QWindowsOpenGLTester::DesktopGl; - - readDriverBugList(gpu, &result); + srCache->insert(qgpu, result); return result; #else // !Q_OS_WINCE return QWindowsOpenGLTester::Gles; diff --git a/src/plugins/platforms/windows/qwindowsopengltester.h b/src/plugins/platforms/windows/qwindowsopengltester.h index 7b6164946e..748885542d 100644 --- a/src/plugins/platforms/windows/qwindowsopengltester.h +++ b/src/plugins/platforms/windows/qwindowsopengltester.h @@ -80,9 +80,12 @@ public: static Renderer requestedGlesRenderer(); static Renderer requestedRenderer(); + static Renderers supportedGlesRenderers(); static Renderers supportedRenderers(); +private: + static QWindowsOpenGLTester::Renderers detectSupportedRenderers(const GpuDescription &gpu, bool glesOnly); static bool testDesktopGL(); }; diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 4cf8fcf4da..2fd0f12c26 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -2259,14 +2259,14 @@ void QWindowsWindow::setCustomMargins(const QMargins &newCustomMargins) } } -void *QWindowsWindow::surface(void *nativeConfig) +void *QWindowsWindow::surface(void *nativeConfig, int *err) { #ifdef QT_NO_OPENGL return 0; #else if (!m_surface) { if (QWindowsStaticOpenGLContext *staticOpenGLContext = QWindowsIntegration::staticOpenGLContext()) - m_surface = staticOpenGLContext->createWindowSurface(m_data.hwnd, nativeConfig); + m_surface = staticOpenGLContext->createWindowSurface(m_data.hwnd, nativeConfig, err); } return m_surface; @@ -2294,6 +2294,12 @@ void QWindowsWindow::registerTouchWindow(QWindowsWindowFunctions::TouchWindowTou #ifndef Q_OS_WINCE if ((QWindowsContext::instance()->systemInfo() & QWindowsContext::SI_SupportsTouch) && window()->type() != Qt::ForeignWindow) { + ULONG touchFlags = 0; + const bool ret = QWindowsContext::user32dll.isTouchWindow(m_data.hwnd, &touchFlags); + // Return if it is not a touch window or the flags are already set by a hook + // such as HCBT_CREATEWND + if (!ret || touchFlags != 0) + return; if (QWindowsContext::user32dll.registerTouchWindow(m_data.hwnd, (ULONG)touchTypes)) setFlag(TouchRegistered); else diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index f0b04fbc47..0089ad07a0 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -248,7 +248,7 @@ public: bool isEnabled() const; void setWindowIcon(const QIcon &icon); - void *surface(void *nativeConfig); + void *surface(void *nativeConfig, int *err); void invalidateSurface() Q_DECL_OVERRIDE; void aboutToMakeCurrent(); diff --git a/src/plugins/platforms/windows/windows.pri b/src/plugins/platforms/windows/windows.pri index 246598677f..e3880a2646 100644 --- a/src/plugins/platforms/windows/windows.pri +++ b/src/plugins/platforms/windows/windows.pri @@ -118,71 +118,15 @@ contains(QT_CONFIG,dynamicgl) { RESOURCES += $$PWD/cursors.qrc } +!wince*: RESOURCES += $$PWD/openglblacklists.qrc + contains(QT_CONFIG, freetype) { DEFINES *= QT_NO_FONTCONFIG - QT_FREETYPE_DIR = $$QT_SOURCE_TREE/src/3rdparty/freetype - + include($$QT_SOURCE_TREE/src/3rdparty/freetype.pri) HEADERS += \ $$PWD/qwindowsfontdatabase_ft.h SOURCES += \ - $$PWD/qwindowsfontdatabase_ft.cpp \ - $$QT_FREETYPE_DIR/src/base/ftbase.c \ - $$QT_FREETYPE_DIR/src/base/ftbbox.c \ - $$QT_FREETYPE_DIR/src/base/ftdebug.c \ - $$QT_FREETYPE_DIR/src/base/ftglyph.c \ - $$QT_FREETYPE_DIR/src/base/ftinit.c \ - $$QT_FREETYPE_DIR/src/base/ftmm.c \ - $$QT_FREETYPE_DIR/src/base/fttype1.c \ - $$QT_FREETYPE_DIR/src/base/ftsynth.c \ - $$QT_FREETYPE_DIR/src/base/ftbitmap.c \ - $$QT_FREETYPE_DIR/src/bdf/bdf.c \ - $$QT_FREETYPE_DIR/src/cache/ftcache.c \ - $$QT_FREETYPE_DIR/src/cff/cff.c \ - $$QT_FREETYPE_DIR/src/cid/type1cid.c \ - $$QT_FREETYPE_DIR/src/gzip/ftgzip.c \ - $$QT_FREETYPE_DIR/src/pcf/pcf.c \ - $$QT_FREETYPE_DIR/src/pfr/pfr.c \ - $$QT_FREETYPE_DIR/src/psaux/psaux.c \ - $$QT_FREETYPE_DIR/src/pshinter/pshinter.c \ - $$QT_FREETYPE_DIR/src/psnames/psmodule.c \ - $$QT_FREETYPE_DIR/src/raster/raster.c \ - $$QT_FREETYPE_DIR/src/sfnt/sfnt.c \ - $$QT_FREETYPE_DIR/src/smooth/smooth.c \ - $$QT_FREETYPE_DIR/src/truetype/truetype.c \ - $$QT_FREETYPE_DIR/src/type1/type1.c \ - $$QT_FREETYPE_DIR/src/type42/type42.c \ - $$QT_FREETYPE_DIR/src/winfonts/winfnt.c \ - $$QT_FREETYPE_DIR/src/lzw/ftlzw.c\ - $$QT_FREETYPE_DIR/src/otvalid/otvalid.c\ - $$QT_FREETYPE_DIR/src/otvalid/otvbase.c\ - $$QT_FREETYPE_DIR/src/otvalid/otvgdef.c\ - $$QT_FREETYPE_DIR/src/otvalid/otvjstf.c\ - $$QT_FREETYPE_DIR/src/otvalid/otvcommn.c\ - $$QT_FREETYPE_DIR/src/otvalid/otvgpos.c\ - $$QT_FREETYPE_DIR/src/otvalid/otvgsub.c\ - $$QT_FREETYPE_DIR/src/otvalid/otvmod.c\ - $$QT_FREETYPE_DIR/src/autofit/afangles.c\ - $$QT_FREETYPE_DIR/src/autofit/afglobal.c\ - $$QT_FREETYPE_DIR/src/autofit/aflatin.c\ - $$QT_FREETYPE_DIR/src/autofit/afmodule.c\ - $$QT_FREETYPE_DIR/src/autofit/afdummy.c\ - $$QT_FREETYPE_DIR/src/autofit/afhints.c\ - $$QT_FREETYPE_DIR/src/autofit/afloader.c\ - $$QT_FREETYPE_DIR/src/autofit/autofit.c - - SOURCES += $$QT_FREETYPE_DIR/src/base/ftsystem.c - - - INCLUDEPATH += \ - $$QT_FREETYPE_DIR/src \ - $$QT_FREETYPE_DIR/include - - TR_EXCLUDE += $$QT_FREETYPE_DIR/* - - DEFINES += FT2_BUILD_LIBRARY - contains(QT_CONFIG, system-zlib) { - DEFINES += FT_CONFIG_OPTION_SYSTEM_ZLIB - } + $$PWD/qwindowsfontdatabase_ft.cpp } else:contains(QT_CONFIG, system-freetype) { include($$QT_SOURCE_TREE/src/platformsupport/fontdatabases/basic/basic.pri) HEADERS += \ |