diff options
author | Liang Qi <liang.qi@theqtcompany.com> | 2016-04-11 08:48:27 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@theqtcompany.com> | 2016-04-11 09:12:36 +0200 |
commit | f34e73a16a3d757057e007874cb5008f16e20f02 (patch) | |
tree | bcc228617cf240773fd09daac1a1a2614b552b68 /src/platformsupport | |
parent | 5380808453728a354ae28aae76e85ac448245cf1 (diff) | |
parent | b9d386f2ccd69c7f6a766a6d90a6024eeb48e90a (diff) |
Merge remote-tracking branch 'origin/5.7' into dev
Conflicts:
src/corelib/kernel/qobject.cpp
src/gui/painting/qpaintengine_raster.cpp
Change-Id: I74e1779832f43d033708dcfd6b666c7b4f0111fb
Diffstat (limited to 'src/platformsupport')
7 files changed, 215 insertions, 173 deletions
diff --git a/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp b/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp index b2e16a409a..f601a196ca 100644 --- a/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp +++ b/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp @@ -215,8 +215,8 @@ bool QDeviceDiscoveryUDev::checkDeviceType(udev_device *dev) return false; if ((m_types & Device_Keyboard) && (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_KEYBOARD"), "1") == 0 )) { - const char *capabilities_key = udev_device_get_sysattr_value(dev, "capabilities/key"); - QStringList val = QString::fromUtf8(capabilities_key).split(QLatin1Char(' '), QString::SkipEmptyParts); + const QString capabilities_key = QString::fromUtf8(udev_device_get_sysattr_value(dev, "capabilities/key")); + const auto val = capabilities_key.splitRef(QLatin1Char(' '), QString::SkipEmptyParts); if (!val.isEmpty()) { bool ok; unsigned long long keys = val.last().toULongLong(&ok, 16); diff --git a/src/platformsupport/glxconvenience/qglxconvenience.cpp b/src/platformsupport/glxconvenience/qglxconvenience.cpp index 870e746a53..7dc29fae6d 100644 --- a/src/platformsupport/glxconvenience/qglxconvenience.cpp +++ b/src/platformsupport/glxconvenience/qglxconvenience.cpp @@ -40,6 +40,7 @@ // We have to include this before the X11 headers dragged in by // qglxconvenience_p.h. #include <QtCore/QByteArray> +#include <QtCore/QScopedPointer> #include "qglxconvenience_p.h" @@ -77,174 +78,182 @@ enum { QVector<int> qglx_buildSpec(const QSurfaceFormat &format, int drawableBit) { - QVector<int> spec(48); - int i = 0; + QVector<int> spec; - spec[i++] = GLX_LEVEL; - spec[i++] = 0; - spec[i++] = GLX_DRAWABLE_TYPE; spec[i++] = drawableBit; + spec << GLX_LEVEL + << 0 - spec[i++] = GLX_RENDER_TYPE; spec[i++] = GLX_RGBA_BIT; + << GLX_RENDER_TYPE + << GLX_RGBA_BIT - spec[i++] = GLX_RED_SIZE; spec[i++] = (format.redBufferSize() == -1) ? 1 : format.redBufferSize(); - spec[i++] = GLX_GREEN_SIZE; spec[i++] = (format.greenBufferSize() == -1) ? 1 : format.greenBufferSize(); - spec[i++] = GLX_BLUE_SIZE; spec[i++] = (format.blueBufferSize() == -1) ? 1 : format.blueBufferSize(); - if (format.hasAlpha()) { - spec[i++] = GLX_ALPHA_SIZE; spec[i++] = format.alphaBufferSize(); - } + << GLX_RED_SIZE + << qMax(1, format.redBufferSize()) - spec[i++] = GLX_DOUBLEBUFFER; spec[i++] = format.swapBehavior() != QSurfaceFormat::SingleBuffer ? True : False; + << GLX_GREEN_SIZE + << qMax(1, format.greenBufferSize()) - spec[i++] = GLX_STEREO; spec[i++] = format.stereo() ? True : False; + << GLX_BLUE_SIZE + << qMax(1, format.blueBufferSize()) - if (format.depthBufferSize() > 0) { - spec[i++] = GLX_DEPTH_SIZE; spec[i++] = format.depthBufferSize(); - } + << GLX_ALPHA_SIZE + << qMax(0, format.alphaBufferSize()); - if (format.stencilBufferSize() > 0) { - spec[i++] = GLX_STENCIL_SIZE; spec[i++] = (format.stencilBufferSize() == -1) ? 1 : format.stencilBufferSize(); - } + if (format.swapBehavior() != QSurfaceFormat::SingleBuffer) + spec << GLX_DOUBLEBUFFER + << True; - if (format.samples() > 1) { - spec[i++] = GLX_SAMPLE_BUFFERS_ARB; - spec[i++] = 1; - spec[i++] = GLX_SAMPLES_ARB; - spec[i++] = format.samples(); - } + if (format.stereo()) + spec << GLX_STEREO + << True; + + if (format.depthBufferSize() != -1) + spec << GLX_DEPTH_SIZE + << format.depthBufferSize(); + + if (format.stencilBufferSize() != -1) + spec << GLX_STENCIL_SIZE + << format.stencilBufferSize(); + + if (format.samples() > 1) + spec << GLX_SAMPLE_BUFFERS_ARB + << 1 + << GLX_SAMPLES_ARB + << format.samples(); + + spec << GLX_DRAWABLE_TYPE + << drawableBit + + << XNone; - spec[i++] = XNone; return spec; } -GLXFBConfig qglx_findConfig(Display *display, int screen , const QSurfaceFormat &format, int drawableBit) -{ - // Allow forcing LIBGL_ALWAYS_SOFTWARE for Qt 5 applications only. - // This is most useful with drivers that only support OpenGL 1. - // We need OpenGL 2, but the user probably doesn't want - // LIBGL_ALWAYS_SOFTWARE in OpenGL 1 apps. - static bool checkedForceSoftwareOpenGL = false; - static bool forceSoftwareOpenGL = false; - if (!checkedForceSoftwareOpenGL) { - // If LIBGL_ALWAYS_SOFTWARE is already set, don't mess with it. - // We want to unset LIBGL_ALWAYS_SOFTWARE at the end so it does not - // get inherited by other processes, of course only if it wasn't - // already set before. - if (!qEnvironmentVariableIsEmpty("QT_XCB_FORCE_SOFTWARE_OPENGL") - && !qEnvironmentVariableIsSet("LIBGL_ALWAYS_SOFTWARE")) - forceSoftwareOpenGL = true; - - checkedForceSoftwareOpenGL = true; - } +namespace { +struct QXcbSoftwareOpenGLEnforcer { + QXcbSoftwareOpenGLEnforcer() { + // Allow forcing LIBGL_ALWAYS_SOFTWARE for Qt 5 applications only. + // This is most useful with drivers that only support OpenGL 1. + // We need OpenGL 2, but the user probably doesn't want + // LIBGL_ALWAYS_SOFTWARE in OpenGL 1 apps. + + if (!checkedForceSoftwareOpenGL) { + // If LIBGL_ALWAYS_SOFTWARE is already set, don't mess with it. + // We want to unset LIBGL_ALWAYS_SOFTWARE at the end so it does not + // get inherited by other processes, of course only if it wasn't + // already set before. + if (!qEnvironmentVariableIsEmpty("QT_XCB_FORCE_SOFTWARE_OPENGL") + && !qEnvironmentVariableIsSet("LIBGL_ALWAYS_SOFTWARE")) + forceSoftwareOpenGL = true; + + checkedForceSoftwareOpenGL = true; + } - if (forceSoftwareOpenGL) - qputenv("LIBGL_ALWAYS_SOFTWARE", QByteArrayLiteral("1")); + if (forceSoftwareOpenGL) + qputenv("LIBGL_ALWAYS_SOFTWARE", QByteArrayLiteral("1")); + } - bool reduced = true; - GLXFBConfig chosenConfig = 0; - QSurfaceFormat reducedFormat = format; - while (!chosenConfig && reduced) { - QVector<int> spec = qglx_buildSpec(reducedFormat, drawableBit); - int confcount = 0; - GLXFBConfig *configs; - configs = glXChooseFBConfig(display, screen,spec.constData(),&confcount); - if (confcount) - { - for (int i = 0; i < confcount; i++) { - chosenConfig = configs[i]; - // Make sure we try to get an ARGB visual if the format asked for an alpha: - if (reducedFormat.hasAlpha()) { - int alphaSize; - glXGetFBConfigAttrib(display,configs[i],GLX_ALPHA_SIZE,&alphaSize); - if (alphaSize > 0) { - XVisualInfo *visual = glXGetVisualFromFBConfig(display, chosenConfig); - bool hasAlpha = false; - -#if !defined(QT_NO_XRENDER) - XRenderPictFormat *pictFormat = XRenderFindVisualFormat(display, visual->visual); - hasAlpha = pictFormat->direct.alphaMask > 0; -#else - hasAlpha = visual->depth == 32; -#endif + ~QXcbSoftwareOpenGLEnforcer() { + // unset LIBGL_ALWAYS_SOFTWARE now so other processes don't inherit it + if (forceSoftwareOpenGL) + qunsetenv("LIBGL_ALWAYS_SOFTWARE"); + } - XFree(visual); + static bool checkedForceSoftwareOpenGL; + static bool forceSoftwareOpenGL; +}; - if (hasAlpha) - break; - } - } else { - break; // Just choose the first in the list if there's no alpha requested - } - } +bool QXcbSoftwareOpenGLEnforcer::checkedForceSoftwareOpenGL = false; +bool QXcbSoftwareOpenGLEnforcer::forceSoftwareOpenGL = false; - XFree(configs); - } - if (!chosenConfig) - reducedFormat = qglx_reduceSurfaceFormat(reducedFormat,&reduced); +template <class T> +struct QXlibScopedPointerDeleter { + static inline void cleanup(T *pointer) { + XFree(pointer); } +}; - // unset LIBGL_ALWAYS_SOFTWARE now so other processes don't inherit it - if (forceSoftwareOpenGL) - qunsetenv("LIBGL_ALWAYS_SOFTWARE"); +template <class T> +using QXlibPointer = QScopedPointer<T, QXlibScopedPointerDeleter<T>>; - return chosenConfig; +template <class T> +using QXlibArrayPointer = QScopedArrayPointer<T, QXlibScopedPointerDeleter<T>>; } -XVisualInfo *qglx_findVisualInfo(Display *display, int screen, QSurfaceFormat *format) +GLXFBConfig qglx_findConfig(Display *display, int screen , QSurfaceFormat format, bool highestPixelFormat, int drawableBit) { - Q_ASSERT(format); + QXcbSoftwareOpenGLEnforcer softwareOpenGLEnforcer; - XVisualInfo *visualInfo = 0; + GLXFBConfig config = 0; - GLXFBConfig config = qglx_findConfig(display,screen,*format); - if (config) { - visualInfo = glXGetVisualFromFBConfig(display, config); - qglx_surfaceFormatFromGLXFBConfig(format, display, config); - } + do { + const QVector<int> spec = qglx_buildSpec(format, drawableBit); - // attempt to fall back to glXChooseVisual - bool reduced = true; - QSurfaceFormat reducedFormat = *format; - while (!visualInfo && reduced) { - QVarLengthArray<int, 13> attribs; - attribs.append(GLX_RGBA); - - if (reducedFormat.redBufferSize() > 0) { - attribs.append(GLX_RED_SIZE); - attribs.append(reducedFormat.redBufferSize()); - } + int confcount = 0; + QXlibArrayPointer<GLXFBConfig> configs(glXChooseFBConfig(display, screen, spec.constData(), &confcount)); - if (reducedFormat.greenBufferSize() > 0) { - attribs.append(GLX_GREEN_SIZE); - attribs.append(reducedFormat.greenBufferSize()); + if (!config && confcount > 0) { + config = configs[0]; + if (highestPixelFormat && !format.hasAlpha()) + break; } - if (reducedFormat.blueBufferSize() > 0) { - attribs.append(GLX_BLUE_SIZE); - attribs.append(reducedFormat.blueBufferSize()); - } + const int requestedRed = qMax(0, format.redBufferSize()); + const int requestedGreen = qMax(0, format.greenBufferSize()); + const int requestedBlue = qMax(0, format.blueBufferSize()); + const int requestedAlpha = qMax(0, format.alphaBufferSize()); - if (reducedFormat.stencilBufferSize() > 0) { - attribs.append(GLX_STENCIL_SIZE); - attribs.append(reducedFormat.stencilBufferSize()); - } + for (int i = 0; i < confcount; i++) { + GLXFBConfig candidate = configs[i]; + + QXlibPointer<XVisualInfo> visual(glXGetVisualFromFBConfig(display, candidate)); - if (reducedFormat.depthBufferSize() > 0) { - attribs.append(GLX_DEPTH_SIZE); - attribs.append(reducedFormat.depthBufferSize()); + const int actualRed = qPopulationCount(visual->red_mask); + const int actualGreen = qPopulationCount(visual->green_mask); + const int actualBlue = qPopulationCount(visual->blue_mask); + const int actualAlpha = visual->depth - actualRed - actualGreen - actualBlue; + + if (requestedRed && actualRed != requestedRed) + continue; + if (requestedGreen && actualGreen != requestedGreen) + continue; + if (requestedBlue && actualBlue != requestedBlue) + continue; + if (requestedAlpha && actualAlpha != requestedAlpha) + continue; + + return candidate; } + } while (qglx_reduceFormat(&format)); + + return config; +} - if (reducedFormat.swapBehavior() != QSurfaceFormat::SingleBuffer) - attribs.append(GLX_DOUBLEBUFFER); +XVisualInfo *qglx_findVisualInfo(Display *display, int screen, QSurfaceFormat *format, int drawableBit) +{ + Q_ASSERT(format); - attribs.append(XNone); + XVisualInfo *visualInfo = 0; - visualInfo = glXChooseVisual(display, screen, attribs.data()); - if (visualInfo) - *format = reducedFormat; + GLXFBConfig config = qglx_findConfig(display, screen, *format, false, drawableBit); + if (config) + visualInfo = glXGetVisualFromFBConfig(display, config); - reducedFormat = qglx_reduceSurfaceFormat(reducedFormat, &reduced); + if (visualInfo) { + qglx_surfaceFormatFromGLXFBConfig(format, display, config); + return visualInfo; } + // attempt to fall back to glXChooseVisual + do { + QVector<int> attribs = qglx_buildSpec(*format, drawableBit); + visualInfo = glXChooseVisual(display, screen, attribs.data()); + + if (visualInfo) { + qglx_surfaceFormatFromVisualInfo(format, display, visualInfo); + return visualInfo; + } + } while (qglx_reduceFormat(format)); + return visualInfo; } @@ -318,33 +327,64 @@ void qglx_surfaceFormatFromVisualInfo(QSurfaceFormat *format, Display *display, format->setStereo(stereo); } -QSurfaceFormat qglx_reduceSurfaceFormat(const QSurfaceFormat &format, bool *reduced) +bool qglx_reduceFormat(QSurfaceFormat *format) { - QSurfaceFormat retFormat = format; - *reduced = true; - - if (retFormat.depthBufferSize() >= 32) { - retFormat.setDepthBufferSize(24); - } else if (retFormat.depthBufferSize() > 0) { - retFormat.setDepthBufferSize(0); - } else if (retFormat.redBufferSize() > 1) { - retFormat.setRedBufferSize(1); - } else if (retFormat.greenBufferSize() > 1) { - retFormat.setGreenBufferSize(1); - } else if (retFormat.blueBufferSize() > 1) { - retFormat.setBlueBufferSize(1); - } else if (retFormat.samples() > 1) { - retFormat.setSamples(qMin(retFormat.samples() / 2, 16)); - } else if (retFormat.stereo()) { - retFormat.setStereo(false); - }else if (retFormat.stencilBufferSize() > 0) { - retFormat.setStencilBufferSize(0); - }else if (retFormat.hasAlpha()) { - retFormat.setAlphaBufferSize(0); - }else if (retFormat.swapBehavior() != QSurfaceFormat::SingleBuffer) { - retFormat.setSwapBehavior(QSurfaceFormat::SingleBuffer); - }else{ - *reduced = false; + Q_ASSERT(format); + + if (format->redBufferSize() > 1) { + format->setRedBufferSize(1); + return true; + } + + if (format->greenBufferSize() > 1) { + format->setGreenBufferSize(1); + return true; + } + + if (format->blueBufferSize() > 1) { + format->setBlueBufferSize(1); + return true; } - return retFormat; + + if (format->swapBehavior() != QSurfaceFormat::SingleBuffer){ + format->setSwapBehavior(QSurfaceFormat::SingleBuffer); + return true; + } + + if (format->samples() > 1) { + format->setSamples(qMin(16, format->samples() / 2)); + return true; + } + + if (format->depthBufferSize() >= 32) { + format->setDepthBufferSize(24); + return true; + } + + if (format->depthBufferSize() > 1) { + format->setDepthBufferSize(1); + return true; + } + + if (format->depthBufferSize() > 0) { + format->setDepthBufferSize(0); + return true; + } + + if (format->hasAlpha()) { + format->setAlphaBufferSize(0); + return true; + } + + if (format->stencilBufferSize() > 1) { + format->setStencilBufferSize(1); + return true; + } + + if (format->stencilBufferSize() > 0) { + format->setStencilBufferSize(0); + return true; + } + + return false; } diff --git a/src/platformsupport/glxconvenience/qglxconvenience_p.h b/src/platformsupport/glxconvenience/qglxconvenience_p.h index 309974f357..d422668584 100644 --- a/src/platformsupport/glxconvenience/qglxconvenience_p.h +++ b/src/platformsupport/glxconvenience/qglxconvenience_p.h @@ -57,11 +57,11 @@ #include <X11/Xlib.h> #include <GL/glx.h> -XVisualInfo *qglx_findVisualInfo(Display *display, int screen, QSurfaceFormat *format); -GLXFBConfig qglx_findConfig(Display *display, int screen, const QSurfaceFormat &format, int drawableBit = GLX_WINDOW_BIT); +QVector<int> qglx_buildSpec(const QSurfaceFormat &format, int drawableBit = GLX_WINDOW_BIT); +XVisualInfo *qglx_findVisualInfo(Display *display, int screen, QSurfaceFormat *format, int drawableBit = GLX_WINDOW_BIT); +GLXFBConfig qglx_findConfig(Display *display, int screen, QSurfaceFormat format, bool highestPixelFormat = false, int drawableBit = GLX_WINDOW_BIT); void qglx_surfaceFormatFromGLXFBConfig(QSurfaceFormat *format, Display *display, GLXFBConfig config); void qglx_surfaceFormatFromVisualInfo(QSurfaceFormat *format, Display *display, XVisualInfo *visualInfo); -QVector<int> qglx_buildSpec(const QSurfaceFormat &format, int drawableBit = GLX_WINDOW_BIT); -QSurfaceFormat qglx_reduceSurfaceFormat(const QSurfaceFormat &format, bool *reduced); +bool qglx_reduceFormat(QSurfaceFormat *format); #endif // QGLXCONVENIENCE_H diff --git a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp index 150445f520..36de1e0c69 100644 --- a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp +++ b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp @@ -101,10 +101,10 @@ QEvdevKeyboardHandler *QEvdevKeyboardHandler::create(const QString &device, bool enableCompose = false; int grab = 0; - QStringList args = specification.split(QLatin1Char(':')); - foreach (const QString &arg, args) { + const auto args = specification.splitRef(QLatin1Char(':')); + for (const QStringRef &arg : args) { if (arg.startsWith(QLatin1String("keymap="))) - keymapFile = arg.mid(7); + keymapFile = arg.mid(7).toString(); else if (arg == QLatin1String("disable-zap")) disableZap = true; else if (arg == QLatin1String("enable-compose")) diff --git a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardmanager.cpp b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardmanager.cpp index 178578e5a2..ffe9f82325 100644 --- a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardmanager.cpp +++ b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardmanager.cpp @@ -135,9 +135,10 @@ void QEvdevKeyboardManager::loadKeymap(const QString &file) // Restore the default, which is either the built-in keymap or // the one given in the plugin spec. QString keymapFromSpec; - foreach (const QString &arg, m_spec.split(QLatin1Char(':'))) { + const auto specs = m_spec.splitRef(QLatin1Char(':')); + for (const QStringRef &arg : specs) { if (arg.startsWith(QLatin1String("keymap="))) - keymapFromSpec = arg.mid(7); + keymapFromSpec = arg.mid(7).toString(); } foreach (QEvdevKeyboardHandler *handler, m_keyboards) { if (keymapFromSpec.isEmpty()) diff --git a/src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp b/src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp index 7f73a7ef94..382b9b1514 100644 --- a/src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp +++ b/src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp @@ -71,8 +71,8 @@ QEvdevMouseHandler *QEvdevMouseHandler::create(const QString &device, const QStr int grab = 0; bool abs = false; - QStringList args = specification.split(QLatin1Char(':')); - foreach (const QString &arg, args) { + const auto args = specification.splitRef(QLatin1Char(':')); + for (const QStringRef &arg : args) { if (arg == QLatin1String("nocompress")) compression = false; else if (arg.startsWith(QLatin1String("dejitter="))) diff --git a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp index 720b032ea5..5e5c931c2c 100644 --- a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp +++ b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp @@ -177,8 +177,9 @@ QStringList QGenericUnixTheme::xdgIconThemePaths() QString xdgDirString = QFile::decodeName(qgetenv("XDG_DATA_DIRS")); if (xdgDirString.isEmpty()) xdgDirString = QLatin1String("/usr/local/share/:/usr/share/"); - foreach (const QString &xdgDir, xdgDirString.split(QLatin1Char(':'))) { - const QFileInfo xdgIconsDir(xdgDir + QStringLiteral("/icons")); + const auto xdgDirs = xdgDirString.splitRef(QLatin1Char(':')); + for (const QStringRef &xdgDir : xdgDirs) { + const QFileInfo xdgIconsDir(xdgDir + QLatin1String("/icons")); if (xdgIconsDir.isDir()) paths.append(xdgIconsDir.absoluteFilePath()); } @@ -626,7 +627,7 @@ public: { Q_ASSERT(!systemFont); const int split = gtkFontName.lastIndexOf(QChar::Space); - float size = gtkFontName.mid(split+1).toFloat(); + float size = gtkFontName.midRef(split + 1).toFloat(); QString fontName = gtkFontName.left(split); systemFont = new QFont(fontName, size); |