diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2018-10-13 00:07:19 +0200 |
---|---|---|
committer | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2018-10-13 00:07:20 +0200 |
commit | fedcaf0256f0094d77f171e4cdca2c4e2469e606 (patch) | |
tree | a7da9f63afbf22fb115a241612a4662e6957cd95 /src | |
parent | 641eb4a96552615d898512723e2093abcaf7fbc1 (diff) | |
parent | 473d9a5fc763d114fbfa1c0d2b5f8d03cab6e972 (diff) |
Merge remote-tracking branch 'origin/5.12' into dev
Change-Id: I2715ee7c694e5579bcedc7bab0ae68e79d5fd0b6
Diffstat (limited to 'src')
-rw-r--r-- | src/3rdparty/freetype/qt_attribution.json | 2 | ||||
-rw-r--r-- | src/3rdparty/wasm/qt_attribution.json | 1 | ||||
-rw-r--r-- | src/gui/image/qimage.cpp | 16 | ||||
-rw-r--r-- | src/gui/image/qimage_conversions.cpp | 17 | ||||
-rw-r--r-- | src/gui/image/qpixmap_win.cpp | 5 | ||||
-rw-r--r-- | src/gui/painting/qdrawhelper.cpp | 9 | ||||
-rw-r--r-- | src/gui/painting/qdrawhelper_neon.cpp | 159 | ||||
-rw-r--r-- | src/network/access/qnetworkreplywasmimpl.cpp | 382 | ||||
-rw-r--r-- | src/network/access/qnetworkreplywasmimpl_p.h | 16 | ||||
-rw-r--r-- | src/platformsupport/eventdispatchers/qeventdispatcher_glib.cpp | 56 | ||||
-rw-r--r-- | src/platformsupport/eventdispatchers/qeventdispatcher_glib_p.h | 3 | ||||
-rw-r--r-- | src/plugins/platforms/windows/openglblacklists/default.json | 3 | ||||
-rw-r--r-- | src/plugins/platforms/winrt/qwinrtbackingstore.cpp | 5 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection.cpp | 55 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection.h | 5 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbintegration.cpp | 3 |
16 files changed, 428 insertions, 309 deletions
diff --git a/src/3rdparty/freetype/qt_attribution.json b/src/3rdparty/freetype/qt_attribution.json index 4be86e92b6..f46541cf2e 100644 --- a/src/3rdparty/freetype/qt_attribution.json +++ b/src/3rdparty/freetype/qt_attribution.json @@ -7,6 +7,8 @@ "Description": "FreeType is a freely available software library to render fonts.", "Homepage": "http://www.freetype.org", + "Version": "2.6.1", + "License": "Freetype Project License or GNU General Public License v2.0 only", "LicenseId": "FTL OR GPL-2.0", "LicenseFile": "LICENSE.txt", diff --git a/src/3rdparty/wasm/qt_attribution.json b/src/3rdparty/wasm/qt_attribution.json index 184e2968cd..2724008157 100644 --- a/src/3rdparty/wasm/qt_attribution.json +++ b/src/3rdparty/wasm/qt_attribution.json @@ -18,4 +18,3 @@ "LicenseFile": "LICENSE", "Copyright": "Copyright (C) 2003 Bitstream,Inc" } - diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 8a4c6b7fda..636cacfb9c 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -1454,7 +1454,8 @@ void QImage::setDevicePixelRatio(qreal scaleFactor) return; detach(); - d->devicePixelRatio = scaleFactor; + if (d) + d->devicePixelRatio = scaleFactor; } /*! @@ -2240,8 +2241,15 @@ bool QImage::reinterpretAsFormat(Format format) return true; if (qt_depthForFormat(format) != qt_depthForFormat(d->format)) return false; - if (!isDetached()) // Detach only if shared, not for read-only data. + if (!isDetached()) { // Detach only if shared, not for read-only data. + QImageData *oldD = d; detach(); + // In case detach() ran out of memory + if (!d) { + d = oldD; + return false; + } + } d->format = format; return true; @@ -3288,6 +3296,8 @@ void QImage::mirrored_inplace(bool horizontal, bool vertical) return; detach(); + if (!d) + return; if (!d->own_data) *this = copy(); @@ -3440,6 +3450,8 @@ void QImage::rgbSwapped_inplace() return; detach(); + if (!d) + return; if (!d->own_data) *this = copy(); diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp index e1f66dceee..964dc0d5c6 100644 --- a/src/gui/image/qimage_conversions.cpp +++ b/src/gui/image/qimage_conversions.cpp @@ -119,6 +119,7 @@ void qGamma_correct_back_to_linear_cs(QImage *image) *****************************************************************************/ // The drawhelper conversions from/to RGB32 are passthroughs which is not always correct for general image conversion +#if !defined(__ARM_NEON__) static void QT_FASTCALL storeRGB32FromARGB32PM(uchar *dest, const uint *src, int index, int count, const QVector<QRgb> *, QDitherInfo *) { @@ -126,6 +127,7 @@ static void QT_FASTCALL storeRGB32FromARGB32PM(uchar *dest, const uint *src, int for (int i = 0; i < count; ++i) d[i] = 0xff000000 | qUnpremultiply(src[i]); } +#endif static void QT_FASTCALL storeRGB32FromARGB32(uchar *dest, const uint *src, int index, int count, const QVector<QRgb> *, QDitherInfo *) @@ -147,6 +149,9 @@ static const uint *QT_FASTCALL fetchRGB32ToARGB32PM(uint *buffer, const uchar *s #ifdef QT_COMPILER_SUPPORTS_SSE4_1 extern void QT_FASTCALL storeRGB32FromARGB32PM_sse4(uchar *dest, const uint *src, int index, int count, const QVector<QRgb> *, QDitherInfo *); +#elif defined(__ARM_NEON__) +extern void QT_FASTCALL storeRGB32FromARGB32PM_neon(uchar *dest, const uint *src, int index, int count, + const QVector<QRgb> *, QDitherInfo *); #endif void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags flags) @@ -175,8 +180,12 @@ void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversio if (qCpuHasFeature(SSE4_1)) store = storeRGB32FromARGB32PM_sse4; else -#endif store = storeRGB32FromARGB32PM; +#elif defined(__ARM_NEON__) + store = storeRGB32FromARGB32PM_neon; +#else + store = storeRGB32FromARGB32PM; +#endif } } if (srcLayout->hasAlphaChannel && !srcLayout->premultiplied && @@ -261,8 +270,12 @@ bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::Im if (qCpuHasFeature(SSE4_1)) store = storeRGB32FromARGB32PM_sse4; else -#endif store = storeRGB32FromARGB32PM; +#elif defined(__ARM_NEON__) + store = storeRGB32FromARGB32PM_neon; +#else + store = storeRGB32FromARGB32PM; +#endif } } if (srcLayout->hasAlphaChannel && !srcLayout->premultiplied && diff --git a/src/gui/image/qpixmap_win.cpp b/src/gui/image/qpixmap_win.cpp index a9e472f8c4..b8d13ac092 100644 --- a/src/gui/image/qpixmap_win.cpp +++ b/src/gui/image/qpixmap_win.cpp @@ -449,8 +449,7 @@ Q_GUI_EXPORT QImage qt_imageFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat = 0 Q_GUI_EXPORT QPixmap qt_pixmapFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat = 0) { - const QImage image = imageFromWinHBITMAP_GetDiBits(bitmap, /* forceQuads */ true, hbitmapFormat); - return QPixmap::fromImage(image); + return QPixmap::fromImage(imageFromWinHBITMAP_GetDiBits(bitmap, /* forceQuads */ true, hbitmapFormat)); } Q_GUI_EXPORT HICON qt_pixmapToWinHICON(const QPixmap &p) @@ -567,7 +566,7 @@ Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon) SelectObject(hdc, oldhdc); //restore state DeleteObject(winBitmap); DeleteDC(hdc); - return QPixmap::fromImage(image); + return QPixmap::fromImage(std::move(image)); } QT_END_NAMESPACE diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 0264059a5c..bbeb9fd9ea 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -6505,10 +6505,19 @@ static void qInitDrawhelperFunctions() const QVector<QRgb> *, QDitherInfo *); extern const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_neon(uint *buffer, const uchar *src, int index, int count, const QVector<QRgb> *, QDitherInfo *); + extern void QT_FASTCALL storeARGB32FromARGB32PM_neon(uchar *dest, const uint *src, int index, int count, + const QVector<QRgb> *, QDitherInfo *); + extern void QT_FASTCALL storeRGBA8888FromARGB32PM_neon(uchar *dest, const uint *src, int index, int count, + const QVector<QRgb> *, QDitherInfo *); + extern void QT_FASTCALL storeRGBXFromARGB32PM_neon(uchar *dest, const uint *src, int index, int count, + const QVector<QRgb> *, QDitherInfo *); qPixelLayouts[QImage::Format_ARGB32].fetchToARGB32PM = fetchARGB32ToARGB32PM_neon; qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_neon; + qPixelLayouts[QImage::Format_ARGB32].storeFromARGB32PM = storeARGB32FromARGB32PM_neon; qPixelLayouts[QImage::Format_RGBA8888].fetchToARGB32PM = fetchRGBA8888ToARGB32PM_neon; qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_neon; + qPixelLayouts[QImage::Format_RGBA8888].storeFromARGB32PM = storeRGBA8888FromARGB32PM_neon; + qPixelLayouts[QImage::Format_RGBX8888].storeFromARGB32PM = storeRGBXFromARGB32PM_neon; #endif #if defined(ENABLE_PIXMAN_DRAWHELPERS) diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp index 98995f485a..629dfe2358 100644 --- a/src/gui/painting/qdrawhelper_neon.cpp +++ b/src/gui/painting/qdrawhelper_neon.cpp @@ -1081,15 +1081,28 @@ const uint * QT_FASTCALL qt_fetchUntransformed_888_neon(uint *buffer, const Oper } #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN -template<bool RGBA> -static inline void convertARGBToARGB32PM_neon(uint *buffer, const uint *src, int count) +static inline uint32x4_t vrgba2argb(uint32x4_t srcVector) { - int i = 0; #if defined(Q_PROCESSOR_ARM_64) const uint8x16_t rgbaMask = { 2, 1, 0, 3, 6, 5, 4, 7, 10, 9, 8, 11, 14, 13, 12, 15}; #else const uint8x8_t rgbaMask = { 2, 1, 0, 3, 6, 5, 4, 7 }; #endif +#if defined(Q_PROCESSOR_ARM_64) + srcVector = vreinterpretq_u32_u8(vqtbl1q_u8(vreinterpretq_u8_u32(srcVector), rgbaMask)); +#else + // no vqtbl1q_u8, so use two vtbl1_u8 + const uint8x8_t low = vtbl1_u8(vreinterpret_u8_u32(vget_low_u32(srcVector)), rgbaMask); + const uint8x8_t high = vtbl1_u8(vreinterpret_u8_u32(vget_high_u32(srcVector)), rgbaMask); + srcVector = vcombine_u32(vreinterpret_u32_u8(low), vreinterpret_u32_u8(high)); +#endif + return srcVector; +} + +template<bool RGBA> +static inline void convertARGBToARGB32PM_neon(uint *buffer, const uint *src, int count) +{ + int i = 0; const uint8x8_t shuffleMask = { 3, 3, 3, 3, 7, 7, 7, 7}; const uint32x4_t blendMask = vdupq_n_u32(0xff000000); @@ -1105,16 +1118,8 @@ static inline void convertARGBToARGB32PM_neon(uint *buffer, const uint *src, int #endif if (alphaSum) { if (alphaSum != 255 * 4) { - if (RGBA) { -#if defined(Q_PROCESSOR_ARM_64) - srcVector = vreinterpretq_u32_u8(vqtbl1q_u8(vreinterpretq_u8_u32(srcVector), rgbaMask)); -#else - // no vqtbl1q_u8 - const uint8x8_t low = vtbl1_u8(vreinterpret_u8_u32(vget_low_u32(srcVector)), rgbaMask); - const uint8x8_t high = vtbl1_u8(vreinterpret_u8_u32(vget_high_u32(srcVector)), rgbaMask); - srcVector = vcombine_u32(vreinterpret_u32_u8(low), vreinterpret_u32_u8(high)); -#endif - } + if (RGBA) + srcVector = vrgba2argb(srcVector); const uint8x8_t s1 = vreinterpret_u8_u32(vget_low_u32(srcVector)); const uint8x8_t s2 = vreinterpret_u8_u32(vget_high_u32(srcVector)); const uint8x8_t alpha1 = vtbl1_u8(s1, shuffleMask); @@ -1128,19 +1133,10 @@ static inline void convertARGBToARGB32PM_neon(uint *buffer, const uint *src, int const uint32x4_t d = vbslq_u32(blendMask, srcVector, vreinterpretq_u32_u8(vcombine_u8(d1, d2))); vst1q_u32(buffer + i, d); } else { - if (RGBA) { -#if defined(Q_PROCESSOR_ARM_64) - srcVector = vreinterpretq_u32_u8(vqtbl1q_u8(vreinterpretq_u8_u32(srcVector), rgbaMask)); -#else - // no vqtbl1q_u8 - const uint8x8_t low = vtbl1_u8(vreinterpret_u8_u32(vget_low_u32(srcVector)), rgbaMask); - const uint8x8_t high = vtbl1_u8(vreinterpret_u8_u32(vget_high_u32(srcVector)), rgbaMask); - srcVector = vcombine_u32(vreinterpret_u32_u8(low), vreinterpret_u32_u8(high)); -#endif - vst1q_u32(buffer + i, srcVector); - } else if (buffer != src) { + if (RGBA) + vst1q_u32(buffer + i, vrgba2argb(srcVector)); + else if (buffer != src) vst1q_u32(buffer + i, srcVector); - } } } else { vst1q_u32(buffer + i, vdupq_n_u32(0)); @@ -1153,6 +1149,91 @@ static inline void convertARGBToARGB32PM_neon(uint *buffer, const uint *src, int } } +static inline float32x4_t reciprocal_mul_ps(float32x4_t a, float mul) +{ + float32x4_t ia = vrecpeq_f32(a); // estimate 1/a + ia = vmulq_f32(vrecpsq_f32(a, ia), vmulq_n_f32(ia, mul)); // estimate improvement step * mul + return ia; +} + +template<bool RGBA, bool RGBx> +static inline void convertARGBFromARGB32PM_neon(uint *buffer, const uint *src, int count) +{ + int i = 0; + const uint32x4_t alphaMask = vdupq_n_u32(0xff000000); + + for (; i < count - 3; i += 4) { + uint32x4_t srcVector = vld1q_u32(src + i); + uint32x4_t alphaVector = vshrq_n_u32(srcVector, 24); +#if defined(Q_PROCESSOR_ARM_64) + uint32_t alphaSum = vaddvq_u32(alphaVector); +#else + // no vaddvq_u32 + uint32x2_t tmp = vpadd_u32(vget_low_u32(alphaVector), vget_high_u32(alphaVector)); + uint32_t alphaSum = vget_lane_u32(vpadd_u32(tmp, tmp), 0); +#endif + if (alphaSum) { + if (alphaSum != 255 * 4) { + if (RGBA) + srcVector = vrgba2argb(srcVector); + const float32x4_t a = vcvtq_f32_u32(alphaVector); + const float32x4_t ia = reciprocal_mul_ps(a, 255.0f); + // Convert 4x(4xU8) to 4x(4xF32) + uint16x8_t tmp1 = vmovl_u8(vget_low_u8(vreinterpretq_u8_u32(srcVector))); + uint16x8_t tmp3 = vmovl_u8(vget_high_u8(vreinterpretq_u8_u32(srcVector))); + float32x4_t src1 = vcvtq_f32_u32(vmovl_u16(vget_low_u16(tmp1))); + float32x4_t src2 = vcvtq_f32_u32(vmovl_u16(vget_high_u16(tmp1))); + float32x4_t src3 = vcvtq_f32_u32(vmovl_u16(vget_low_u16(tmp3))); + float32x4_t src4 = vcvtq_f32_u32(vmovl_u16(vget_high_u16(tmp3))); + src1 = vmulq_lane_f32(src1, vget_low_f32(ia), 0); + src2 = vmulq_lane_f32(src2, vget_low_f32(ia), 1); + src3 = vmulq_lane_f32(src3, vget_high_f32(ia), 0); + src4 = vmulq_lane_f32(src4, vget_high_f32(ia), 1); + // Convert 4x(4xF32) back to 4x(4xU8) (over a 8.1 fixed point format to get rounding) + tmp1 = vcombine_u16(vrshrn_n_u32(vcvtq_n_u32_f32(src1, 1), 1), + vrshrn_n_u32(vcvtq_n_u32_f32(src2, 1), 1)); + tmp3 = vcombine_u16(vrshrn_n_u32(vcvtq_n_u32_f32(src3, 1), 1), + vrshrn_n_u32(vcvtq_n_u32_f32(src4, 1), 1)); + uint32x4_t dstVector = vreinterpretq_u32_u8(vcombine_u8(vmovn_u16(tmp1), vmovn_u16(tmp3))); + // Overwrite any undefined results from alpha==0 with zeros: +#if defined(Q_PROCESSOR_ARM_64) + uint32x4_t srcVectorAlphaMask = vceqzq_u32(alphaVector); +#else + uint32x4_t srcVectorAlphaMask = vceqq_u32(alphaVector, vdupq_n_u32(0)); +#endif + dstVector = vbicq_u32(dstVector, srcVectorAlphaMask); + // Restore or mask alpha values: + if (RGBx) + dstVector = vorrq_u32(alphaMask, dstVector); + else + dstVector = vbslq_u32(alphaMask, srcVector, dstVector); + vst1q_u32(&buffer[i], dstVector); + } else { + // 4xAlpha==255, no change except if we are doing RGBA->ARGB: + if (RGBA) + vst1q_u32(&buffer[i], vrgba2argb(srcVector)); + else if (buffer != src) + vst1q_u32(&buffer[i], srcVector); + } + } else { + // 4xAlpha==0, always zero, except if output is RGBx: + if (RGBx) + vst1q_u32(&buffer[i], alphaMask); + else + vst1q_u32(&buffer[i], vdupq_n_u32(0)); + } + } + + SIMD_EPILOGUE(i, count, 3) { + uint v = qUnpremultiply(src[i]); + if (RGBx) + v = 0xff000000 | v; + if (RGBA) + v = ARGB2RGBA(v); + buffer[i] = v; + } +} + void QT_FASTCALL convertARGB32ToARGB32PM_neon(uint *buffer, int count, const QVector<QRgb> *) { convertARGBToARGB32PM_neon<false>(buffer, buffer, count); @@ -1177,6 +1258,34 @@ const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_neon(uint *buffer, const uchar * return buffer; } +void QT_FASTCALL storeRGB32FromARGB32PM_neon(uchar *dest, const uint *src, int index, int count, + const QVector<QRgb> *, QDitherInfo *) +{ + uint *d = reinterpret_cast<uint *>(dest) + index; + convertARGBFromARGB32PM_neon<false,true>(d, src, count); +} + +void QT_FASTCALL storeARGB32FromARGB32PM_neon(uchar *dest, const uint *src, int index, int count, + const QVector<QRgb> *, QDitherInfo *) +{ + uint *d = reinterpret_cast<uint *>(dest) + index; + convertARGBFromARGB32PM_neon<false,false>(d, src, count); +} + +void QT_FASTCALL storeRGBA8888FromARGB32PM_neon(uchar *dest, const uint *src, int index, int count, + const QVector<QRgb> *, QDitherInfo *) +{ + uint *d = reinterpret_cast<uint *>(dest) + index; + convertARGBFromARGB32PM_neon<true,false>(d, src, count); +} + +void QT_FASTCALL storeRGBXFromARGB32PM_neon(uchar *dest, const uint *src, int index, int count, + const QVector<QRgb> *, QDitherInfo *) +{ + uint *d = reinterpret_cast<uint *>(dest) + index; + convertARGBFromARGB32PM_neon<true,true>(d, src, count); +} + #endif // Q_BYTE_ORDER == Q_LITTLE_ENDIAN QT_END_NAMESPACE diff --git a/src/network/access/qnetworkreplywasmimpl.cpp b/src/network/access/qnetworkreplywasmimpl.cpp index 9c2ff8fb89..23ca62acd4 100644 --- a/src/network/access/qnetworkreplywasmimpl.cpp +++ b/src/network/access/qnetworkreplywasmimpl.cpp @@ -49,10 +49,135 @@ #include <private/qnetworkaccessmanager_p.h> #include <private/qnetworkfile_p.h> -#include <iostream> +#include <emscripten.h> +#include <emscripten/bind.h> +#include <emscripten/val.h> QT_BEGIN_NAMESPACE +using namespace emscripten; + +static void q_requestErrorCallback(val event) +{ + val xhr = event["target"]; + + quintptr func = xhr["data-handler"].as<quintptr>(); + QNetworkReplyWasmImplPrivate *reply = reinterpret_cast<QNetworkReplyWasmImplPrivate*>(func); + Q_ASSERT(reply); + + int statusCode = xhr["status"].as<int>(); + + QString reasonStr = QString::fromStdString(xhr["statusText"].as<std::string>()); + + reply->setReplyAttributes(func, statusCode, reasonStr); + + if (statusCode >= 400 && !reasonStr.isEmpty()) + reply->emitReplyError(reply->statusCodeFromHttp(statusCode, reply->request.url()), reasonStr); +} + +static void q_progressCallback(val event) +{ + val xhr = event["target"]; + + QNetworkReplyWasmImplPrivate *reply = + reinterpret_cast<QNetworkReplyWasmImplPrivate*>(xhr["data-handler"].as<quintptr>()); + Q_ASSERT(reply); + + if (xhr["lengthComputable"].as<bool>() && xhr["status"].as<int>() < 400) + reply->emitDataReadProgress(xhr["loaded"].as<qint64>(), xhr["total"].as<qint64>()); + +} + +static void q_loadCallback(val event) +{ + val xhr = event["target"]; + + QNetworkReplyWasmImplPrivate *reply = + reinterpret_cast<QNetworkReplyWasmImplPrivate*>(xhr["data-handler"].as<quintptr>()); + Q_ASSERT(reply); + + int status = xhr["status"].as<int>(); + if (status >= 300) { + q_requestErrorCallback(event); + return; + } + QString statusText = QString::fromStdString(xhr["statusText"].as<std::string>()); + if (status == 200 || status == 203) { + QString responseString; + const std::string responseType = xhr["responseType"].as<std::string>(); + if (responseType.length() == 0 || responseType == "document" || responseType == "text") { + responseString = QString::fromStdWString(xhr["responseText"].as<std::wstring>()); + } else if (responseType == "json") { + responseString = + QString::fromStdWString(val::global("JSON").call<std::wstring>("stringify", xhr["response"])); + } else if (responseType == "arraybuffer" || responseType == "blob") { + // handle this data in the FileReader, triggered by the call to readAsArrayBuffer + val reader = val::global("FileReader").new_(); + reader.set("onload", val::module_property("QNetworkReplyWasmImplPrivate_readBinary")); + reader.set("data-handler", xhr["data-handler"]); + reader.call<void>("readAsArrayBuffer", xhr["response"]); + } + + int readyState = xhr["readyState"].as<int>(); + + if (readyState == 4) { // done + reply->setReplyAttributes(xhr["data-handler"].as<quintptr>(), status, statusText); + if (!responseString.isEmpty()) + reply->dataReceived(responseString.toUtf8(), responseString.size()); + } + } + if (status >= 400 && !statusText.isEmpty()) + reply->emitReplyError(reply->statusCodeFromHttp(status, reply->request.url()), statusText); +} + +static void q_responseHeadersCallback(val event) +{ + val xhr = event["target"]; + + if (xhr["readyState"].as<int>() == 2) { // HEADERS_RECEIVED + std::string responseHeaders = xhr.call<std::string>("getAllResponseHeaders"); + if (!responseHeaders.empty()) { + QNetworkReplyWasmImplPrivate *reply = + reinterpret_cast<QNetworkReplyWasmImplPrivate*>(xhr["data-handler"].as<quintptr>()); + Q_ASSERT(reply); + + reply->headersReceived(QString::fromStdString(responseHeaders)); + } + } +} + +static void q_readBinary(val event) +{ + val fileReader = event["target"]; + + QNetworkReplyWasmImplPrivate *reply = + reinterpret_cast<QNetworkReplyWasmImplPrivate*>(fileReader["data-handler"].as<quintptr>()); + Q_ASSERT(reply); + + // Set up source typed array + val result = fileReader["result"]; // ArrayBuffer + val Uint8Array = val::global("Uint8Array"); + val sourceTypedArray = Uint8Array.new_(result); + + // Allocate and set up destination typed array + const quintptr size = result["byteLength"].as<quintptr>(); + QByteArray buffer(size, Qt::Uninitialized); + + val destinationTypedArray = Uint8Array.new_(val::module_property("HEAPU8")["buffer"], + reinterpret_cast<quintptr>(buffer.data()), size); + destinationTypedArray.call<void>("set", sourceTypedArray); + reply->dataReceived(buffer, buffer.size()); +} + + +EMSCRIPTEN_BINDINGS(network_module) { + function("QNetworkReplyWasmImplPrivate_requestErrorCallback", q_requestErrorCallback); + function("QNetworkReplyWasmImplPrivate_progressCallback", q_progressCallback); + function("QNetworkReplyWasmImplPrivate_loadCallback", q_loadCallback); + function("QNetworkReplyWasmImplPrivate_responseHeadersCallback", q_responseHeadersCallback); + function("QNetworkReplyWasmImplPrivate_readBinary", q_readBinary); +} + QNetworkReplyWasmImplPrivate::QNetworkReplyWasmImplPrivate() : QNetworkReplyPrivate() , managerPrivate(0) @@ -172,226 +297,80 @@ void QNetworkReplyWasmImplPrivate::setup(QNetworkAccessManager::Operation op, co doSendRequest(); } -void QNetworkReplyWasmImplPrivate::onLoadCallback(void *data, int statusCode, int statusReason, int readyState, int buffer, int bufferSize) -{ - QNetworkReplyWasmImplPrivate *handler = reinterpret_cast<QNetworkReplyWasmImplPrivate*>(data); - - const QString reasonStr = QString::fromUtf8(reinterpret_cast<char *>(statusReason)); - - switch (readyState) { - case 0://unsent - break; - case 1://opened - break; - case 2://headers received - break; - case 3://loading - break; - case 4: {//done - handler->q_func()->setAttribute(QNetworkRequest::HttpStatusCodeAttribute, statusCode); - if (!reasonStr.isEmpty()) - handler->q_func()->setAttribute(QNetworkRequest::HttpReasonPhraseAttribute, reasonStr); - - if (statusCode >= 400) { - if (!reasonStr.isEmpty()) - handler->emitReplyError(handler->statusCodeFromHttp(statusCode, handler->request.url()), reasonStr); - } else { - handler->dataReceived(reinterpret_cast<char *>(buffer), bufferSize); - } - } - break; - }; - } - -void QNetworkReplyWasmImplPrivate::onProgressCallback(void* data, int bytesWritten, int total, uint timestamp) -{ - Q_UNUSED(timestamp); - - QNetworkReplyWasmImplPrivate *handler = reinterpret_cast<QNetworkReplyWasmImplPrivate*>(data); - handler->emitDataReadProgress(bytesWritten, total); -} - -void QNetworkReplyWasmImplPrivate::onRequestErrorCallback(void* data, int statusCode, int statusReason) +void QNetworkReplyWasmImplPrivate::setReplyAttributes(quintptr data, int statusCode, const QString &statusReason) { - QString reasonStr = QString::fromUtf8(reinterpret_cast<char *>(statusReason)); - QNetworkReplyWasmImplPrivate *handler = reinterpret_cast<QNetworkReplyWasmImplPrivate*>(data); + Q_ASSERT(handler); handler->q_func()->setAttribute(QNetworkRequest::HttpStatusCodeAttribute, statusCode); - if (!reasonStr.isEmpty()) - handler->q_func()->setAttribute(QNetworkRequest::HttpReasonPhraseAttribute, reasonStr); - - if (statusCode >= 400) { - if (!reasonStr.isEmpty()) - handler->emitReplyError(handler->statusCodeFromHttp(statusCode, handler->request.url()), reasonStr); - } -} - -void QNetworkReplyWasmImplPrivate::onResponseHeadersCallback(void* data, int headers) -{ - QNetworkReplyWasmImplPrivate *handler = reinterpret_cast<QNetworkReplyWasmImplPrivate*>(data); - handler->headersReceived(reinterpret_cast<char *>(headers)); + if (!statusReason.isEmpty()) + handler->q_func()->setAttribute(QNetworkRequest::HttpReasonPhraseAttribute, statusReason); } void QNetworkReplyWasmImplPrivate::doSendRequest() { Q_Q(QNetworkReplyWasmImpl); totalDownloadSize = 0; - jsRequest(QString::fromUtf8(q->methodName()), // GET POST - request.url().toString(), - (void *)&onLoadCallback, - (void *)&onProgressCallback, - (void *)&onRequestErrorCallback, - (void *)&onResponseHeadersCallback); -} - -/* const QString &body, const QList<QPair<QByteArray, QByteArray> > &headers ,*/ -void QNetworkReplyWasmImplPrivate::jsRequest(const QString &verb, const QString &url, - void *loadCallback, void *progressCallback, - void *errorCallback, void *onResponseHeadersCallback) -{ - QString extraDataString; - - QByteArray extraData; - if (outgoingData) - extraData = outgoingData->readAll(); - if (extraData.size() > 0) - extraDataString.fromUtf8(extraData); + val xhr = val::global("XMLHttpRequest").new_(); + std::string verb = q->methodName().toStdString(); - if (extraDataString.size() >= 0 && verb == QStringLiteral("POST") && extraDataString.startsWith(QStringLiteral("?"))) - extraDataString.remove(QStringLiteral("?")); + QUrl url; + QString extraDataString; - // Probably a good idea to save any shared pointers as members in C++ - // so the objects they point to survive as long as you need them + if (request.url().hasQuery()) { //strip query from url + extraDataString = request.url().query(QUrl::FullyEncoded); + QString urlStr = request.url().toString(); + url.setUrl(urlStr.left(urlStr.indexOf("?"))); + } else { + url = request.url(); + } + xhr.call<void>("open", verb, url.toString().toStdString()); - QStringList headersList; - for (auto header : request.rawHeaderList()) - headersList << QString::fromUtf8(header + ":" + request.rawHeader(header)); + xhr.set("onerror", val::module_property("QNetworkReplyWasmImplPrivate_requestErrorCallback")); + xhr.set("onload", val::module_property("QNetworkReplyWasmImplPrivate_loadCallback")); + xhr.set("onprogress", val::module_property("QNetworkReplyWasmImplPrivate_progressCallback")); + xhr.set("onreadystatechange", val::module_property("QNetworkReplyWasmImplPrivate_responseHeadersCallback")); - EM_ASM_ARGS({ - var verb = Pointer_stringify($0); - var url = Pointer_stringify($1); - var onLoadCallbackPointer = $2; - var onProgressCallbackPointer = $3; - var onErrorCallbackPointer = $4; - var onHeadersCallback = $5; - var handler = $8; + xhr.set("data-handler", val(quintptr(reinterpret_cast<void *>(this)))); - var dataToSend; - var extraRequestData = Pointer_stringify($6); // request parameters - var headersData = Pointer_stringify($7); + QByteArray contentType = request.rawHeader("Content-Type"); - var xhr; - xhr = new XMLHttpRequest(); - xhr.responseType = 'arraybuffer'; + // handle extra data + val dataToSend = val::null(); + QByteArray extraData; - xhr.open(verb, url, true); //async + if (outgoingData) // data from post request + extraData = outgoingData->readAll(); - function handleError(xhrStatusCode, xhrStatusText) { - var errorPtr = allocate(intArrayFromString(xhrStatusText), 'i8', ALLOC_NORMAL); - Runtime.dynCall('viii', onErrorCallbackPointer, [handler, xhrStatusCode, errorPtr]); - _free(errorPtr); + if (contentType.contains("text") || + contentType.contains("json") || + contentType.contains("form")) { + if (extraData.size() > 0) + extraDataString.fromUtf8(extraData); + } + if (contentType.contains("json")) { + if (!extraDataString.isEmpty()) { + xhr.set("responseType", val("json")); + dataToSend = val(extraDataString.toStdString()); } + } + if (contentType.contains("form")) { //construct form data + if (!extraDataString.isEmpty()) { + val formData = val::global("FormData").new_(); + QStringList formList = extraDataString.split('&'); - if (headersData) { - var headers = headersData.split("&"); - for (var i = 0; i < headers.length; i++) { - var header = headers[i].split(":")[0]; - var value = headers[i].split(":")[1]; - - if (verb === 'POST' && value.toLowerCase().includes('json')) { - if (extraRequestData) { - xhr.responseType = 'json'; - dataToSend = extraRequestData; - } - } - if (verb === 'POST' && value.toLowerCase().includes('form')) { - if (extraRequestData) { - var formData = new FormData(); - var extra = extraRequestData.split("&"); - for (var i = 0; i < extra.length; i++) { - formData.append(extra[i].split("=")[0],extra[i].split("=")[1]); - } - dataToSend = formData; - } - } - xhr.setRequestHeader(header, value); + for (auto formEntry : formList) { + formData.call<void>("append", formEntry.split('=')[0].toStdString(), formEntry.split('=')[1].toStdString()); } + dataToSend = formData; } - - xhr.onprogress = function(e) { - switch (xhr.status) { - case 200: - case 206: - case 300: - case 301: - case 302: { - var date = xhr.getResponseHeader('Last-Modified'); - date = ((date != null) ? new Date(date).getTime() / 1000 : 0); - Runtime.dynCall('viiii', onProgressCallbackPointer, [handler, e.loaded, e.total, date]); - } - break; - } - }; - - xhr.onreadystatechange = function() { - if (this.readyState == this.HEADERS_RECEIVED) { - var responseStr = this.getAllResponseHeaders(); - if (responseStr.length > 0) { - var ptr = allocate(intArrayFromString(responseStr), 'i8', ALLOC_NORMAL); - Runtime.dynCall('vii', onHeadersCallback, [handler, ptr]); - _free(ptr); - } - } - }; - - xhr.onload = function(e) { - if (xhr.status >= 300) { //error - handleError(xhr.status, xhr.statusText); - } else { - if (this.status == 200 || this.status == 203) { - var datalength; - var byteArray = 0; - var buffer; - if (this.responseType.length === 0 || this.responseType === 'document') { - byteArray = new Uint8Array(this.responseText); - } else if (this.responseType === 'json') { - var jsonResponse = JSON.stringify(this.response); - buffer = allocate(intArrayFromString(jsonResponse), 'i8', ALLOC_NORMAL); - datalength = jsonResponse.length; - } else if (this.responseType === 'arraybuffer') { - byteArray = new Uint8Array(xhr.response); - } - if (byteArray != 0 ) { - datalength = byteArray.length; - buffer = _malloc(datalength); - HEAPU8.set(byteArray, buffer); - } - var reasonPtr = allocate(intArrayFromString(this.statusText), 'i8', ALLOC_NORMAL); - Runtime.dynCall('viiiiii', onLoadCallbackPointer, [handler, this.status, reasonPtr, this.readyState, buffer, datalength]); - _free(buffer); - _free(reasonPtr); - } - } - }; - - xhr.onerror = function(e) { - handleError(xhr.status, xhr.statusText); - }; - //TODO other operations, handle user/pass, handle binary data, data streaming - xhr.send(dataToSend); - - }, verb.toLatin1().data(), - url.toLatin1().data(), - loadCallback, - progressCallback, - errorCallback, - onResponseHeadersCallback, - extraDataString.size() > 0 ? extraDataString.toLatin1().data() : extraData.data(), - headersList.join(QStringLiteral("&")).toLatin1().data(), - this - ); + } + // set request headers + for (auto header : request.rawHeaderList()) { + xhr.call<void>("setRequestHeader", header.toStdString(), request.rawHeader(header).toStdString()); + } + xhr.call<void>("send", dataToSend); } void QNetworkReplyWasmImplPrivate::emitReplyError(QNetworkReply::NetworkError errorCode, const QString &errorString) @@ -414,10 +393,10 @@ void QNetworkReplyWasmImplPrivate::emitDataReadProgress(qint64 bytesReceived, qi percentFinished = (bytesReceived / bytesTotal) * 100; - emit q->downloadProgress(bytesReceived, totalDownloadSize); + emit q->downloadProgress(bytesReceived, bytesTotal); } -void QNetworkReplyWasmImplPrivate::dataReceived(char *buffer, int bufferSize) +void QNetworkReplyWasmImplPrivate::dataReceived(const QByteArray &buffer, int bufferSize) { Q_Q(QNetworkReplyWasmImpl); @@ -481,11 +460,10 @@ static int parseHeaderName(const QByteArray &headerName) } -void QNetworkReplyWasmImplPrivate::headersReceived(char *buffer) +void QNetworkReplyWasmImplPrivate::headersReceived(const QString &bufferString) { Q_Q(QNetworkReplyWasmImpl); - QString bufferString = QString::fromUtf8(buffer); if (!bufferString.isEmpty()) { QStringList headers = bufferString.split(QString::fromUtf8("\r\n"), QString::SkipEmptyParts); diff --git a/src/network/access/qnetworkreplywasmimpl_p.h b/src/network/access/qnetworkreplywasmimpl_p.h index a707390503..69c90de41a 100644 --- a/src/network/access/qnetworkreplywasmimpl_p.h +++ b/src/network/access/qnetworkreplywasmimpl_p.h @@ -95,7 +95,6 @@ public: private: QByteArray methodName() const; - }; class QNetworkReplyWasmImplPrivate: public QNetworkReplyPrivate @@ -106,19 +105,12 @@ public: QNetworkAccessManagerPrivate *managerPrivate; void doSendRequest(); - - void jsRequest(const QString &verb, const QString &url, void *, void *, void *, void *); - - static void onLoadCallback(void *data, int statusCode, int statusReason, int readyState, int textBuffer, int size); - static void onProgressCallback(void *data, int done, int bytesTotal, uint timestamp); - static void onRequestErrorCallback(void *data, int statusCode, int statusReason); - static void onStateChangedCallback(int status); - static void onResponseHeadersCallback(void *data, int headers); + static void setReplyAttributes(quintptr data, int statusCode, const QString &statusReason); void emitReplyError(QNetworkReply::NetworkError errorCode, const QString &); void emitDataReadProgress(qint64 done, qint64 total); - void dataReceived(char *buffer, int bufferSize); - void headersReceived(char *buffer); + void dataReceived(const QByteArray &buffer, int bufferSize); + void headersReceived(const QString &bufferString); void setup(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice *outgoingData); @@ -148,6 +140,4 @@ public: QT_END_NAMESPACE -//Q_DECLARE_METATYPE(QNetworkRequest::KnownHeaders) - #endif // QNETWORKREPLYWASMIMPL_H diff --git a/src/platformsupport/eventdispatchers/qeventdispatcher_glib.cpp b/src/platformsupport/eventdispatchers/qeventdispatcher_glib.cpp index 06f0aa6747..dc4785071f 100644 --- a/src/platformsupport/eventdispatchers/qeventdispatcher_glib.cpp +++ b/src/platformsupport/eventdispatchers/qeventdispatcher_glib.cpp @@ -48,26 +48,78 @@ QT_BEGIN_NAMESPACE +struct GUserEventSource +{ + GSource source; + QPAEventDispatcherGlib *q; +}; + +static gboolean userEventSourcePrepare(GSource *source, gint *timeout) +{ + Q_UNUSED(timeout) + GUserEventSource *userEventSource = reinterpret_cast<GUserEventSource *>(source); + QPAEventDispatcherGlib *dispatcher = userEventSource->q; + if (dispatcher->m_flags & QEventLoop::ExcludeUserInputEvents) + return QWindowSystemInterface::nonUserInputEventsQueued(); + else + return QWindowSystemInterface::windowSystemEventsQueued() > 0; +} + +static gboolean userEventSourceCheck(GSource *source) +{ + return userEventSourcePrepare(source, 0); +} + +static gboolean userEventSourceDispatch(GSource *source, GSourceFunc, gpointer) +{ + GUserEventSource *userEventSource = reinterpret_cast<GUserEventSource *>(source); + QPAEventDispatcherGlib *dispatcher = userEventSource->q; + QWindowSystemInterface::sendWindowSystemEvents(dispatcher->m_flags); + return true; +} + +static GSourceFuncs userEventSourceFuncs = { + userEventSourcePrepare, + userEventSourceCheck, + userEventSourceDispatch, + NULL, + NULL, + NULL +}; + QPAEventDispatcherGlibPrivate::QPAEventDispatcherGlibPrivate(GMainContext *context) : QEventDispatcherGlibPrivate(context) { + Q_Q(QPAEventDispatcherGlib); + userEventSource = reinterpret_cast<GUserEventSource *>(g_source_new(&userEventSourceFuncs, + sizeof(GUserEventSource))); + userEventSource->q = q; + g_source_set_can_recurse(&userEventSource->source, true); + g_source_attach(&userEventSource->source, mainContext); } + QPAEventDispatcherGlib::QPAEventDispatcherGlib(QObject *parent) : QEventDispatcherGlib(*new QPAEventDispatcherGlibPrivate, parent) , m_flags(QEventLoop::AllEvents) { + Q_D(QPAEventDispatcherGlib); + d->userEventSource->q = this; } QPAEventDispatcherGlib::~QPAEventDispatcherGlib() { + Q_D(QPAEventDispatcherGlib); + + g_source_destroy(&d->userEventSource->source); + g_source_unref(&d->userEventSource->source); + d->userEventSource = 0; } bool QPAEventDispatcherGlib::processEvents(QEventLoop::ProcessEventsFlags flags) { m_flags = flags; - const bool didSendEvents = QEventDispatcherGlib::processEvents(m_flags); - return QWindowSystemInterface::sendWindowSystemEvents(m_flags) || didSendEvents; + return QEventDispatcherGlib::processEvents(m_flags); } QT_END_NAMESPACE diff --git a/src/platformsupport/eventdispatchers/qeventdispatcher_glib_p.h b/src/platformsupport/eventdispatchers/qeventdispatcher_glib_p.h index 5930dc68e7..085a1c52f3 100644 --- a/src/platformsupport/eventdispatchers/qeventdispatcher_glib_p.h +++ b/src/platformsupport/eventdispatchers/qeventdispatcher_glib_p.h @@ -71,11 +71,14 @@ public: QEventLoop::ProcessEventsFlags m_flags; }; +struct GUserEventSource; + class QPAEventDispatcherGlibPrivate : public QEventDispatcherGlibPrivate { Q_DECLARE_PUBLIC(QPAEventDispatcherGlib) public: QPAEventDispatcherGlibPrivate(GMainContext *context = 0); + GUserEventSource *userEventSource; }; diff --git a/src/plugins/platforms/windows/openglblacklists/default.json b/src/plugins/platforms/windows/openglblacklists/default.json index b618d8567a..3cfa7e3856 100644 --- a/src/plugins/platforms/windows/openglblacklists/default.json +++ b/src/plugins/platforms/windows/openglblacklists/default.json @@ -144,9 +144,8 @@ }, { "id": 12, - "description": "Intel HD Graphics 620 crash in conjunction with shader caches (QTBUG-64697)", + "description": "Intel HD Graphics crash in conjunction with shader caches (QTBUG-64697) - disable for all Intel GPUs", "vendor_id": "0x8086", - "device_id": [ "0x5916" ], "os": { "type": "win" }, diff --git a/src/plugins/platforms/winrt/qwinrtbackingstore.cpp b/src/plugins/platforms/winrt/qwinrtbackingstore.cpp index b3bf52f09b..c23d48b2dd 100644 --- a/src/plugins/platforms/winrt/qwinrtbackingstore.cpp +++ b/src/plugins/platforms/winrt/qwinrtbackingstore.cpp @@ -118,11 +118,14 @@ void QWinRTBackingStore::flush(QWindow *window, const QRegion ®ion, const QPo if (d->size.isEmpty()) return; + const QRect bounds = region.boundingRect() & d->paintDevice.rect(); + if (bounds.isEmpty()) + return; + const bool ok = d->context->makeCurrent(window); if (!ok) qWarning("unable to flush"); - const QRect bounds = region.boundingRect(); glBindTexture(GL_TEXTURE_2D, d->fbo->texture()); // TODO: when ANGLE GLES3 support is finished, use the glPixelStorei functions to minimize upload glTexSubImage2D(GL_TEXTURE_2D, 0, 0, bounds.y(), d->size.width(), bounds.height(), diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 6dda6487c8..4e24c970b4 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -90,25 +90,6 @@ #include <xcb/render.h> #endif -#if defined(Q_CC_GNU) && defined(Q_OF_ELF) -static xcb_generic_event_t *local_xcb_poll_for_queued_event(xcb_connection_t *c) - __attribute__((weakref("xcb_poll_for_queued_event"))); - -static inline void checkXcbPollForQueuedEvent() -{ } -#else -#include <dlfcn.h> -typedef xcb_generic_event_t * (*XcbPollForQueuedEventFunctionPointer)(xcb_connection_t *c); -static XcbPollForQueuedEventFunctionPointer local_xcb_poll_for_queued_event; - -static inline void checkXcbPollForQueuedEvent() -{ -#ifdef RTLD_DEFAULT - local_xcb_poll_for_queued_event = (XcbPollForQueuedEventFunctionPointer)dlsym(RTLD_DEFAULT, "xcb_poll_for_queued_event"); -#endif -} -#endif - QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(lcQpaXInput, "qt.qpa.input") @@ -1365,39 +1346,19 @@ bool QXcbConnection::peekEventQueue(PeekerCallback peeker, void *peekerData, QXcbEventReader::QXcbEventReader(QXcbConnection *connection) : m_connection(connection) { - checkXcbPollForQueuedEvent(); } void QXcbEventReader::start() { - if (local_xcb_poll_for_queued_event) { - connect(this, SIGNAL(eventPending()), m_connection, SLOT(processXcbEvents()), Qt::QueuedConnection); - connect(this, SIGNAL(finished()), m_connection, SLOT(processXcbEvents())); - QThread::start(); - } else { - // Must be done after we have an event-dispatcher. By posting a method invocation - // we are sure that by the time the method is called we have an event-dispatcher. - QMetaObject::invokeMethod(this, "registerForEvents", Qt::QueuedConnection); - } -} - -void QXcbEventReader::registerForEvents() -{ - QSocketNotifier *notifier = new QSocketNotifier(xcb_get_file_descriptor(m_connection->xcb_connection()), QSocketNotifier::Read, this); - connect(notifier, SIGNAL(activated(int)), m_connection, SLOT(processXcbEvents())); - - QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::eventDispatcher; - connect(dispatcher, SIGNAL(aboutToBlock()), m_connection, SLOT(processXcbEvents())); - connect(dispatcher, SIGNAL(awake()), m_connection, SLOT(processXcbEvents())); + connect(this, &QXcbEventReader::eventPending, m_connection, &QXcbConnection::processXcbEvents, Qt::QueuedConnection); + connect(this, &QXcbEventReader::finished, m_connection, &QXcbConnection::processXcbEvents); + QThread::start(); } void QXcbEventReader::registerEventDispatcher(QAbstractEventDispatcher *dispatcher) { - // flush the xcb connection before the EventDispatcher is going to block - // In the non-threaded case processXcbEvents is called before going to block, - // which flushes the connection. - if (local_xcb_poll_for_queued_event) - connect(dispatcher, SIGNAL(aboutToBlock()), m_connection, SLOT(flush())); + // Flush the xcb connection before the event dispatcher is going to block. + connect(dispatcher, &QAbstractEventDispatcher::aboutToBlock, m_connection, &QXcbConnection::flush); } void QXcbEventReader::run() @@ -1406,7 +1367,7 @@ void QXcbEventReader::run() while (m_connection && (event = xcb_wait_for_event(m_connection->xcb_connection()))) { m_mutex.lock(); addEvent(event); - while (m_connection && (event = local_xcb_poll_for_queued_event(m_connection->xcb_connection()))) + while (m_connection && (event = xcb_poll_for_queued_event(m_connection->xcb_connection()))) addEvent(event); m_mutex.unlock(); emit eventPending(); @@ -1430,10 +1391,6 @@ void QXcbEventReader::addEvent(xcb_generic_event_t *event) QXcbEventArray *QXcbEventReader::lock() { m_mutex.lock(); - if (!local_xcb_poll_for_queued_event) { - while (xcb_generic_event_t *event = xcb_poll_for_event(m_connection->xcb_connection())) - m_events << event; - } return &m_events; } diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 1e28ef8fac..db45031cf4 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -326,9 +326,6 @@ public: signals: void eventPending(); -private slots: - void registerForEvents(); - private: void addEvent(xcb_generic_event_t *event); @@ -493,8 +490,6 @@ public: bool hasShmFd() const { return has_shm_fd; } bool hasXSync() const { return has_sync_extension; } - bool threadedEventHandling() const { return m_reader->isRunning(); } - xcb_timestamp_t getTimestamp(); xcb_window_t getSelectionOwner(xcb_atom_t atom) const; xcb_window_t getQtSelectionOwner(); diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index 9fc1189181..db8dc09025 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -308,8 +308,7 @@ bool QXcbIntegration::hasCapability(QPlatformIntegration::Capability cap) const { const auto *connection = qAsConst(m_connections).first(); if (const auto *integration = connection->glIntegration()) - return cap != ThreadedOpenGL - || (connection->threadedEventHandling() && integration->supportsThreadedOpenGL()); + return cap != ThreadedOpenGL || integration->supportsThreadedOpenGL(); return false; } |