diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2018-09-09 01:00:10 +0200 |
---|---|---|
committer | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2018-09-09 01:00:10 +0200 |
commit | be27bf02f4b9c976887cc20dfa013d41e810cfe6 (patch) | |
tree | e587ccabc0c382f1b4c00af242304294262eea97 /src/gui | |
parent | 59fc64cfc5139a66b69222ab3bd5389438e90f2f (diff) | |
parent | 5474f28c42ce0c853ddd08a8fd2f31948fcd968b (diff) |
Merge remote-tracking branch 'origin/5.12' into dev
Change-Id: I36cda712b4cf960de70e497aef52fbc491099f1c
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/doc/src/qtgui.qdoc | 5 | ||||
-rw-r--r-- | src/gui/kernel/qopenglcontext.cpp | 86 | ||||
-rw-r--r-- | src/gui/painting/qdrawhelper.cpp | 58 | ||||
-rw-r--r-- | src/gui/util/qshadergraphloader.cpp | 15 | ||||
-rw-r--r-- | src/gui/util/qshadernodesloader.cpp | 8 | ||||
-rw-r--r-- | src/gui/util/qshadernodesloader_p.h | 1 | ||||
-rw-r--r-- | src/gui/vulkan/qvulkanwindow.cpp | 14 |
7 files changed, 122 insertions, 65 deletions
diff --git a/src/gui/doc/src/qtgui.qdoc b/src/gui/doc/src/qtgui.qdoc index a425c8a84d..53fd55bd39 100644 --- a/src/gui/doc/src/qtgui.qdoc +++ b/src/gui/doc/src/qtgui.qdoc @@ -46,11 +46,12 @@ \snippet code/doc_src_qtgui.pro 0 + \if !defined(qtforpython) If you use \l qmake to build your projects, \l{Qt GUI} is included by default. To disable Qt GUI, add the following line to your \c .pro file: \snippet code/doc_src_qtgui.pro 1 - + \endif */ /*! @@ -75,10 +76,12 @@ \snippet code/doc_src_qtgui.pro 0 + \if !defined(qtforpython) If you use \l qmake to build your projects, Qt GUI is included by default. To disable Qt GUI, add the following line to your \c .pro file: \snippet code/doc_src_qtgui.pro 1 + \endif \section1 Application Windows diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index cd50294a6c..d64d31a9e8 100644 --- a/src/gui/kernel/qopenglcontext.cpp +++ b/src/gui/kernel/qopenglcontext.cpp @@ -985,62 +985,60 @@ bool QOpenGLContext::makeCurrent(QSurface *surface) } QOpenGLContext *previous = QOpenGLContextPrivate::setCurrentContext(this); + if (!d->platformGLContext->makeCurrent(surface->surfaceHandle())) { + QOpenGLContextPrivate::setCurrentContext(previous); + return false; + } - if (d->platformGLContext->makeCurrent(surface->surfaceHandle())) { - static bool needsWorkaroundSet = false; - static bool needsWorkaround = false; + static bool needsWorkaroundSet = false; + static bool needsWorkaround = false; - if (!needsWorkaroundSet) { - QByteArray env; + if (!needsWorkaroundSet) { + QByteArray env; #ifdef Q_OS_ANDROID - env = qgetenv(QByteArrayLiteral("QT_ANDROID_DISABLE_GLYPH_CACHE_WORKAROUND")); - needsWorkaround = env.isEmpty() || env == QByteArrayLiteral("0") || env == QByteArrayLiteral("false"); + env = qgetenv(QByteArrayLiteral("QT_ANDROID_DISABLE_GLYPH_CACHE_WORKAROUND")); + needsWorkaround = env.isEmpty() || env == QByteArrayLiteral("0") || env == QByteArrayLiteral("false"); #endif - env = qgetenv(QByteArrayLiteral("QT_ENABLE_GLYPH_CACHE_WORKAROUND")); - if (env == QByteArrayLiteral("1") || env == QByteArrayLiteral("true")) - needsWorkaround = true; - - if (!needsWorkaround) { - const char *rendererString = reinterpret_cast<const char *>(functions()->glGetString(GL_RENDERER)); - if (rendererString) - needsWorkaround = - qstrncmp(rendererString, "Mali-4xx", 6) == 0 // Mali-400, Mali-450 - || qstrcmp(rendererString, "Mali-T880") == 0 - || qstrncmp(rendererString, "Adreno (TM) 2xx", 13) == 0 // Adreno 200, 203, 205 - || qstrncmp(rendererString, "Adreno 2xx", 8) == 0 // Same as above but without the '(TM)' - || qstrncmp(rendererString, "Adreno (TM) 3xx", 13) == 0 // Adreno 302, 305, 320, 330 - || qstrncmp(rendererString, "Adreno 3xx", 8) == 0 // Same as above but without the '(TM)' - || qstrncmp(rendererString, "Adreno (TM) 4xx", 13) == 0 // Adreno 405, 418, 420, 430 - || qstrncmp(rendererString, "Adreno 4xx", 8) == 0 // Same as above but without the '(TM)' - || qstrncmp(rendererString, "Adreno (TM) 5xx", 13) == 0 // Adreno 505, 506, 510, 530, 540 - || qstrncmp(rendererString, "Adreno 5xx", 8) == 0 // Same as above but without the '(TM)' - || qstrncmp(rendererString, "Adreno (TM) 6xx", 13) == 0 // Adreno 610, 620, 630 - || qstrncmp(rendererString, "Adreno 6xx", 8) == 0 // Same as above but without the '(TM)' - || qstrcmp(rendererString, "GC800 core") == 0 - || qstrcmp(rendererString, "GC1000 core") == 0 - || strstr(rendererString, "GC2000") != 0 - || qstrcmp(rendererString, "Immersion.16") == 0; - } - needsWorkaroundSet = true; + env = qgetenv(QByteArrayLiteral("QT_ENABLE_GLYPH_CACHE_WORKAROUND")); + if (env == QByteArrayLiteral("1") || env == QByteArrayLiteral("true")) + needsWorkaround = true; + + if (!needsWorkaround) { + const char *rendererString = reinterpret_cast<const char *>(functions()->glGetString(GL_RENDERER)); + if (rendererString) + needsWorkaround = + qstrncmp(rendererString, "Mali-4xx", 6) == 0 // Mali-400, Mali-450 + || qstrcmp(rendererString, "Mali-T880") == 0 + || qstrncmp(rendererString, "Adreno (TM) 2xx", 13) == 0 // Adreno 200, 203, 205 + || qstrncmp(rendererString, "Adreno 2xx", 8) == 0 // Same as above but without the '(TM)' + || qstrncmp(rendererString, "Adreno (TM) 3xx", 13) == 0 // Adreno 302, 305, 320, 330 + || qstrncmp(rendererString, "Adreno 3xx", 8) == 0 // Same as above but without the '(TM)' + || qstrncmp(rendererString, "Adreno (TM) 4xx", 13) == 0 // Adreno 405, 418, 420, 430 + || qstrncmp(rendererString, "Adreno 4xx", 8) == 0 // Same as above but without the '(TM)' + || qstrncmp(rendererString, "Adreno (TM) 5xx", 13) == 0 // Adreno 505, 506, 510, 530, 540 + || qstrncmp(rendererString, "Adreno 5xx", 8) == 0 // Same as above but without the '(TM)' + || qstrncmp(rendererString, "Adreno (TM) 6xx", 13) == 0 // Adreno 610, 620, 630 + || qstrncmp(rendererString, "Adreno 6xx", 8) == 0 // Same as above but without the '(TM)' + || qstrcmp(rendererString, "GC800 core") == 0 + || qstrcmp(rendererString, "GC1000 core") == 0 + || strstr(rendererString, "GC2000") != 0 + || qstrcmp(rendererString, "Immersion.16") == 0; } + needsWorkaroundSet = true; + } - if (needsWorkaround) - d->workaround_brokenFBOReadBack = true; + if (needsWorkaround) + d->workaround_brokenFBOReadBack = true; - d->surface = surface; + d->surface = surface; - d->shareGroup->d_func()->deletePendingResources(this); + d->shareGroup->d_func()->deletePendingResources(this); #ifndef QT_NO_DEBUG - QOpenGLContextPrivate::toggleMakeCurrentTracker(this, true); + QOpenGLContextPrivate::toggleMakeCurrentTracker(this, true); #endif - return true; - } - - QOpenGLContextPrivate::setCurrentContext(previous); - - return false; + return true; } /*! diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 8f189994f1..582e403e4c 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -5689,6 +5689,46 @@ static inline int qRgbAvg(QRgb rgb) return (qRed(rgb) * 5 + qGreen(rgb) * 6 + qBlue(rgb) * 5) / 16; } +static inline QRgb rgbBlend(QRgb d, QRgb s, uint rgbAlpha) +{ +#if defined(__SSE2__) + __m128i vd = _mm_cvtsi32_si128(d); + __m128i vs = _mm_cvtsi32_si128(s); + __m128i va = _mm_cvtsi32_si128(rgbAlpha); + const __m128i vz = _mm_setzero_si128(); + vd = _mm_unpacklo_epi8(vd, vz); + vs = _mm_unpacklo_epi8(vs, vz); + va = _mm_unpacklo_epi8(va, vz); + __m128i vb = _mm_xor_si128(_mm_set1_epi16(255), va); + vs = _mm_mullo_epi16(vs, va); + vd = _mm_mullo_epi16(vd, vb); + vd = _mm_add_epi16(vd, vs); + vd = _mm_add_epi16(vd, _mm_srli_epi16(vd, 8)); + vd = _mm_add_epi16(vd, _mm_set1_epi16(0x80)); + vd = _mm_srli_epi16(vd, 8); + vd = _mm_packus_epi16(vd, vd); + return _mm_cvtsi128_si32(vd); +#else + const int dr = qRed(d); + const int dg = qGreen(d); + const int db = qBlue(d); + + const int sr = qRed(s); + const int sg = qGreen(s); + const int sb = qBlue(s); + + const int mr = qRed(rgbAlpha); + const int mg = qGreen(rgbAlpha); + const int mb = qBlue(rgbAlpha); + + const int nr = qt_div_255(sr * mr + dr * (255 - mr)); + const int ng = qt_div_255(sg * mg + dg * (255 - mg)); + const int nb = qt_div_255(sb * mb + db * (255 - mb)); + + return 0xff000000 | (nr << 16) | (ng << 8) | nb; +#endif +} + static inline void alphargbblend_generic(uint coverage, QRgba64 *dest, int x, const QRgba64 &srcLinear, const QRgba64 &src, const QColorProfile *colorProfile) { if (coverage == 0xff000000) { @@ -5711,20 +5751,20 @@ static inline void alphargbblend_generic(uint coverage, QRgba64 *dest, int x, co } } -static inline void alphargbblend_argb32(quint32 *dst, uint coverage, QRgba64 srcLinear, quint32 src, const QColorProfile *colorProfile) +static inline void alphargbblend_argb32(quint32 *dst, uint coverage, const QRgba64 &srcLinear, quint32 src, const QColorProfile *colorProfile) { if (coverage == 0xff000000) { // nothing } else if (coverage == 0xffffffff) { *dst = src; - } else { - if (*dst >= 0xff000000) { - rgbBlendPixel(dst, coverage, srcLinear, colorProfile); - } else { - // Give up and do a naive gray alphablend. Needed to deal with ARGB32 and invalid ARGB32_premultiplied, see QTBUG-60571 - const int a = qRgbAvg(coverage); - *dst = INTERPOLATE_PIXEL_255(src, a, *dst, 255 - a); - } + } else if (*dst < 0xff000000) { + // Give up and do a naive gray alphablend. Needed to deal with ARGB32 and invalid ARGB32_premultiplied, see QTBUG-60571 + const int a = qRgbAvg(coverage); + *dst = INTERPOLATE_PIXEL_255(src, a, *dst, 255 - a); + } else if (!colorProfile) { + *dst = rgbBlend(*dst, src, coverage); + } else { + rgbBlendPixel(dst, coverage, srcLinear, colorProfile); } } diff --git a/src/gui/util/qshadergraphloader.cpp b/src/gui/util/qshadergraphloader.cpp index 8d92c73a5a..99a9f7869e 100644 --- a/src/gui/util/qshadergraphloader.cpp +++ b/src/gui/util/qshadergraphloader.cpp @@ -39,6 +39,8 @@ #include "qshadergraphloader_p.h" +#include "qshadernodesloader_p.h" + #include <QtCore/qdebug.h> #include <QtCore/qiodevice.h> #include <QtCore/qjsonarray.h> @@ -129,6 +131,19 @@ void QShaderGraphLoader::load() bool hasError = false; + const auto prototypesValue = root.value(QStringLiteral("prototypes")); + if (!prototypesValue.isUndefined()) { + if (prototypesValue.isObject()) { + QShaderNodesLoader loader; + loader.load(prototypesValue.toObject()); + m_prototypes.unite(loader.nodes()); + } else { + qWarning() << "Invalid prototypes property, should be an object"; + m_status = Error; + return; + } + } + const auto nodes = nodesValue.toArray(); for (const auto &nodeValue : nodes) { if (!nodeValue.isObject()) { diff --git a/src/gui/util/qshadernodesloader.cpp b/src/gui/util/qshadernodesloader.cpp index db34b6d44d..692653ee44 100644 --- a/src/gui/util/qshadernodesloader.cpp +++ b/src/gui/util/qshadernodesloader.cpp @@ -99,11 +99,15 @@ void QShaderNodesLoader::load() } const auto root = document.object(); + load(root); +} +void QShaderNodesLoader::load(const QJsonObject &prototypesObject) +{ bool hasError = false; - for (const auto &property : root.keys()) { - const auto nodeValue = root.value(property); + for (const auto &property : prototypesObject.keys()) { + const auto nodeValue = prototypesObject.value(property); if (!nodeValue.isObject()) { qWarning() << "Invalid node found"; hasError = true; diff --git a/src/gui/util/qshadernodesloader_p.h b/src/gui/util/qshadernodesloader_p.h index 2696e958b6..0bec871857 100644 --- a/src/gui/util/qshadernodesloader_p.h +++ b/src/gui/util/qshadernodesloader_p.h @@ -78,6 +78,7 @@ public: Q_GUI_EXPORT void setDevice(QIODevice *device) Q_DECL_NOTHROW; Q_GUI_EXPORT void load(); + Q_GUI_EXPORT void load(const QJsonObject &prototypesObject); private: Status m_status; diff --git a/src/gui/vulkan/qvulkanwindow.cpp b/src/gui/vulkan/qvulkanwindow.cpp index 7dea743ea8..e45a16170e 100644 --- a/src/gui/vulkan/qvulkanwindow.cpp +++ b/src/gui/vulkan/qvulkanwindow.cpp @@ -2694,15 +2694,11 @@ QImage QVulkanWindow::grab() system differences between OpenGL and Vulkan. By pre-multiplying the projection matrix with this matrix, applications can - continue to assume OpenGL-style Y coordinates in clip space (i.e. Y pointing - upwards), and can set minDepth and maxDepth to 0 and 1, respectively, - without any further corrections to the vertex Z positions, while using the - projection matrices retrieved from the QMatrix4x4 functions, such as - QMatrix4x4::perspective(), as-is. - - \note With vertex data following the default OpenGL rules (that is, the - front face being CCW), the correct winding order in the rasterization state - after applying this matrix is clockwise (\c{VK_FRONT_FACE_CLOCKWISE}). + continue to assume that Y is pointing upwards, and can set minDepth and + maxDepth in the viewport to 0 and 1, respectively, without having to do any + further corrections to the vertex Z positions. Geometry from OpenGL + applications can then be used as-is, assuming a rasterization state matching + the OpenGL culling and front face settings. */ QMatrix4x4 QVulkanWindow::clipCorrectionMatrix() { |