summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-10-13 00:07:19 +0200
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-10-13 00:07:20 +0200
commitfedcaf0256f0094d77f171e4cdca2c4e2469e606 (patch)
treea7da9f63afbf22fb115a241612a4662e6957cd95 /src
parent641eb4a96552615d898512723e2093abcaf7fbc1 (diff)
parent473d9a5fc763d114fbfa1c0d2b5f8d03cab6e972 (diff)
Merge remote-tracking branch 'origin/5.12' into dev
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/freetype/qt_attribution.json2
-rw-r--r--src/3rdparty/wasm/qt_attribution.json1
-rw-r--r--src/gui/image/qimage.cpp16
-rw-r--r--src/gui/image/qimage_conversions.cpp17
-rw-r--r--src/gui/image/qpixmap_win.cpp5
-rw-r--r--src/gui/painting/qdrawhelper.cpp9
-rw-r--r--src/gui/painting/qdrawhelper_neon.cpp159
-rw-r--r--src/network/access/qnetworkreplywasmimpl.cpp382
-rw-r--r--src/network/access/qnetworkreplywasmimpl_p.h16
-rw-r--r--src/platformsupport/eventdispatchers/qeventdispatcher_glib.cpp56
-rw-r--r--src/platformsupport/eventdispatchers/qeventdispatcher_glib_p.h3
-rw-r--r--src/plugins/platforms/windows/openglblacklists/default.json3
-rw-r--r--src/plugins/platforms/winrt/qwinrtbackingstore.cpp5
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp55
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h5
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.cpp3
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 &region, 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;
}