From f8d41309c8a62345c32da180507bcd60316dbb0c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 2 Nov 2018 14:44:13 -0700 Subject: Use qsizetype for qt_memfill functions Just in case the image is larger than 2 GB (512 megapixels). Change-Id: I343f2beed55440a7ac0bfffd15636cbc68dfa13d Reviewed-by: Allan Sandfeld Jensen (cherry picked from commit 1e2bf51d3e5d891db3c1383e6567d1c77dfc8973) Reviewed-by: Thiago Macieira --- src/gui/painting/qdrawhelper.cpp | 17 ++++++++++------- src/gui/painting/qdrawhelper_mips_dsp.cpp | 2 +- src/gui/painting/qdrawhelper_mips_dsp_p.h | 2 +- src/gui/painting/qdrawhelper_neon.cpp | 2 +- src/gui/painting/qdrawhelper_neon_p.h | 2 +- src/gui/painting/qdrawhelper_p.h | 26 +++++++++++++------------- src/gui/painting/qdrawhelper_sse2.cpp | 6 +++--- src/gui/painting/qdrawhelper_x86_p.h | 4 ++-- 8 files changed, 32 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 6265d51037..7b8104914c 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -6278,7 +6278,7 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = #if defined(Q_CC_MSVC) && !defined(_MIPS_) template -inline void qt_memfill_template(T *dest, T color, int count) +inline void qt_memfill_template(T *dest, T color, qsizetype count) { while (count--) *dest++ = color; @@ -6287,9 +6287,12 @@ inline void qt_memfill_template(T *dest, T color, int count) #else template -inline void qt_memfill_template(T *dest, T color, int count) +inline void qt_memfill_template(T *dest, T color, qsizetype count) { - int n = (count + 7) / 8; + if (!count) + return; + + qsizetype n = (count + 7) / 8; switch (count & 0x07) { case 0: do { *dest++ = color; Q_FALLTHROUGH(); @@ -6305,7 +6308,7 @@ inline void qt_memfill_template(T *dest, T color, int count) } template <> -inline void qt_memfill_template(quint16 *dest, quint16 value, int count) +inline void qt_memfill_template(quint16 *dest, quint16 value, qsizetype count) { if (count < 3) { switch (count) { @@ -6327,19 +6330,19 @@ inline void qt_memfill_template(quint16 *dest, quint16 value, int count) } #endif -void qt_memfill64(quint64 *dest, quint64 color, int count) +void qt_memfill64(quint64 *dest, quint64 color, qsizetype count) { qt_memfill_template(dest, color, count); } #if !defined(__SSE2__) -void qt_memfill16(quint16 *dest, quint16 color, int count) +void qt_memfill16(quint16 *dest, quint16 color, qsizetype count) { qt_memfill_template(dest, color, count); } #endif #if !defined(__SSE2__) && !defined(__ARM_NEON__) && !defined(__MIPS_DSP__) -void qt_memfill32(quint32 *dest, quint32 color, int count) +void qt_memfill32(quint32 *dest, quint32 color, qsizetype count) { qt_memfill_template(dest, color, count); } diff --git a/src/gui/painting/qdrawhelper_mips_dsp.cpp b/src/gui/painting/qdrawhelper_mips_dsp.cpp index e92a6606de..17597deb1d 100644 --- a/src/gui/painting/qdrawhelper_mips_dsp.cpp +++ b/src/gui/painting/qdrawhelper_mips_dsp.cpp @@ -43,7 +43,7 @@ QT_BEGIN_NAMESPACE -void qt_memfill32(quint32 *dest, quint32 color, int count) +void qt_memfill32(quint32 *dest, quint32 color, qsizetype count) { qt_memfill32_asm_mips_dsp(dest, color, count); } diff --git a/src/gui/painting/qdrawhelper_mips_dsp_p.h b/src/gui/painting/qdrawhelper_mips_dsp_p.h index 36c4af2732..a3d0410274 100644 --- a/src/gui/painting/qdrawhelper_mips_dsp_p.h +++ b/src/gui/painting/qdrawhelper_mips_dsp_p.h @@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE #if defined(QT_COMPILER_SUPPORTS_MIPS_DSP) -extern "C" void qt_memfill32_asm_mips_dsp(quint32 *dest, quint32 value, int count); +extern "C" void qt_memfill32_asm_mips_dsp(quint32 *dest, quint32 value, qsizetype count); extern "C" void comp_func_SourceOver_asm_mips_dsp(uint *dest, const uint *src, int length, uint const_alpha); diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp index 3fbd651f96..0d99bd54fb 100644 --- a/src/gui/painting/qdrawhelper_neon.cpp +++ b/src/gui/painting/qdrawhelper_neon.cpp @@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE -void qt_memfill32(quint32 *dest, quint32 value, int count) +void qt_memfill32(quint32 *dest, quint32 value, qsizetype count) { const int epilogueSize = count % 16; #if defined(Q_CC_GHS) || defined(Q_CC_MSVC) diff --git a/src/gui/painting/qdrawhelper_neon_p.h b/src/gui/painting/qdrawhelper_neon_p.h index 40475a9bde..19e1f21a3b 100644 --- a/src/gui/painting/qdrawhelper_neon_p.h +++ b/src/gui/painting/qdrawhelper_neon_p.h @@ -123,7 +123,7 @@ void qt_transform_image_rgb16_on_rgb16_neon(uchar *destPixels, int dbpl, const QTransform &targetRectTransform, int const_alpha); -void qt_memfill32_neon(quint32 *dest, quint32 value, int count); +void qt_memfill32_neon(quint32 *dest, quint32 value, qsizetype count); void qt_memrotate90_16_neon(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl); void qt_memrotate270_16_neon(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl); diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index fb08261205..f2e0819bea 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -163,9 +163,9 @@ extern SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::N extern DrawHelper qDrawHelper[QImage::NImageFormats]; void qBlendTexture(int count, const QSpan *spans, void *userData); -extern void qt_memfill64(quint64 *dest, quint64 value, int count); -extern void qt_memfill32(quint32 *dest, quint32 value, int count); -extern void qt_memfill16(quint16 *dest, quint16 value, int count); +extern void qt_memfill64(quint64 *dest, quint64 value, qsizetype count); +extern void qt_memfill32(quint32 *dest, quint32 value, qsizetype count); +extern void qt_memfill16(quint16 *dest, quint16 value, qsizetype count); typedef void (QT_FASTCALL *CompositionFunction)(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha); typedef void (QT_FASTCALL *CompositionFunction64)(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha); @@ -888,35 +888,35 @@ inline quint24::operator uint() const } template Q_STATIC_TEMPLATE_FUNCTION -void qt_memfill(T *dest, T value, int count); +void qt_memfill(T *dest, T value, qsizetype count); -template<> inline void qt_memfill(quint64 *dest, quint64 color, int count) +template<> inline void qt_memfill(quint64 *dest, quint64 color, qsizetype count) { qt_memfill64(dest, color, count); } -template<> inline void qt_memfill(quint32 *dest, quint32 color, int count) +template<> inline void qt_memfill(quint32 *dest, quint32 color, qsizetype count) { qt_memfill32(dest, color, count); } -template<> inline void qt_memfill(quint16 *dest, quint16 color, int count) +template<> inline void qt_memfill(quint16 *dest, quint16 color, qsizetype count) { qt_memfill16(dest, color, count); } -template<> inline void qt_memfill(quint8 *dest, quint8 color, int count) +template<> inline void qt_memfill(quint8 *dest, quint8 color, qsizetype count) { memset(dest, color, count); } template -inline void qt_memfill(T *dest, T value, int count) +inline void qt_memfill(T *dest, T value, qsizetype count) { if (!count) return; - int n = (count + 7) / 8; + qsizetype n = (count + 7) / 8; switch (count & 0x07) { case 0: do { *dest++ = value; Q_FALLTHROUGH(); @@ -937,7 +937,7 @@ inline void qt_rectfill(T *dest, T value, { char *d = reinterpret_cast(dest + x) + y * stride; if (uint(stride) == (width * sizeof(T))) { - qt_memfill(reinterpret_cast(d), value, width * height); + qt_memfill(reinterpret_cast(d), value, qsizetype(width) * height); } else { for (int j = 0; j < height; ++j) { dest = reinterpret_cast(d); @@ -958,7 +958,7 @@ do { \ /* Duff's device */ \ uint *_d = (uint*)(dest) + length; \ const uint *_s = (uint*)(src) + length; \ - int n = ((length) + 7) / 8; \ + qsizetype n = ((length) + 7) / 8; \ switch ((length) & 0x07) \ { \ case 0: do { *--_d = *--_s; Q_FALLTHROUGH(); \ @@ -978,7 +978,7 @@ do { \ /* Duff's device */ \ ushort *_d = (ushort*)(dest); \ const ushort *_s = (const ushort*)(src); \ - int n = ((length) + 7) / 8; \ + qsizetype n = ((length) + 7) / 8; \ switch ((length) & 0x07) \ { \ case 0: do { *_d++ = *_s++; Q_FALLTHROUGH(); \ diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp index 3212ffdd2d..2ae8a092df 100644 --- a/src/gui/painting/qdrawhelper_sse2.cpp +++ b/src/gui/painting/qdrawhelper_sse2.cpp @@ -233,7 +233,7 @@ void QT_FASTCALL comp_func_Source_sse2(uint *dst, const uint *src, int length, u } } -void qt_memfill32(quint32 *dest, quint32 value, int count) +void qt_memfill32(quint32 *dest, quint32 value, qsizetype count) { if (count < 7) { switch (count) { @@ -263,7 +263,7 @@ void qt_memfill32(quint32 *dest, quint32 value, int count) } } - int count128 = count / 4; + qsizetype count128 = count / 4; __m128i *dst128 = reinterpret_cast<__m128i*>(dest); __m128i *end128 = dst128 + count128; const __m128i value128 = _mm_set_epi32(value, value, value, value); @@ -314,7 +314,7 @@ void QT_FASTCALL comp_func_solid_SourceOver_sse2(uint *destPixels, int length, u } } -void qt_memfill16(quint16 *dest, quint16 value, int count) +void qt_memfill16(quint16 *dest, quint16 value, qsizetype count) { if (count < 3) { switch (count) { diff --git a/src/gui/painting/qdrawhelper_x86_p.h b/src/gui/painting/qdrawhelper_x86_p.h index cefc213999..964d522fd2 100644 --- a/src/gui/painting/qdrawhelper_x86_p.h +++ b/src/gui/painting/qdrawhelper_x86_p.h @@ -57,8 +57,8 @@ QT_BEGIN_NAMESPACE #ifdef __SSE2__ -void qt_memfill32(quint32 *dest, quint32 value, int count); -void qt_memfill16(quint16 *dest, quint16 value, int count); +void qt_memfill32(quint32 *dest, quint32 value, qsizetype count); +void qt_memfill16(quint16 *dest, quint16 value, qsizetype count); void qt_bitmapblit32_sse2(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 &color, const uchar *src, int width, int height, int stride); -- cgit v1.2.3 From e1b0dfc1d406e132fd42ecebcc7bd260e9ef8f9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 31 Jul 2019 14:14:00 +0200 Subject: macOS: Choose appropriate NSWindow depth based on surface format Change-Id: I67e63412096ca11a8f056f5755525311756906ef Reviewed-by: Andy Nichols Reviewed-by: Timur Pocheptsov --- src/plugins/platforms/cocoa/qcocoabackingstore.mm | 31 +++++++++++++++++++++++ src/plugins/platforms/cocoa/qcocoawindow.mm | 15 ----------- 2 files changed, 31 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm index 5d5e406d8a..cb453f7613 100644 --- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm +++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm @@ -75,6 +75,37 @@ QCFType QCocoaBackingStore::colorSpace() const QNSWindowBackingStore::QNSWindowBackingStore(QWindow *window) : QCocoaBackingStore(window) { + // Choose an appropriate window depth based on the requested surface format. + // On deep color displays the default bit depth is 16-bit, so unless we need + // that level of precision we opt out of it (and the expensive RGB32 -> RGB64 + // conversions that come with it if our backingstore depth does not match). + + NSWindow *nsWindow = static_cast(window->handle())->view().window; + auto colorSpaceName = NSColorSpaceFromDepth(nsWindow.depthLimit); + + static const int kDefaultBitDepth = 8; + auto surfaceFormat = window->requestedFormat(); + auto bitsPerSample = qMax(kDefaultBitDepth, qMax(surfaceFormat.redBufferSize(), + qMax(surfaceFormat.greenBufferSize(), surfaceFormat.blueBufferSize()))); + + // NSBestDepth does not seem to guarantee a window depth deep enough for the + // given bits per sample, even if documented as such. For example, requesting + // 10 bits per sample will not give us a 16-bit format, even if that's what's + // available. Work around this by manually bumping the bit depth. + bitsPerSample = !(bitsPerSample & (bitsPerSample - 1)) + ? bitsPerSample : qNextPowerOfTwo(bitsPerSample); + + auto bestDepth = NSBestDepth(colorSpaceName, bitsPerSample, 0, NO, nullptr); + + // Disable dynamic depth limit, otherwise our depth limit will be overwritten + // by AppKit if the window moves to a screen with a different depth. We call + // this before setting the depth limit, as the call will reset the depth to 0. + [nsWindow setDynamicDepthLimit:NO]; + + qCDebug(lcQpaBackingStore) << "Using" << NSBitsPerSampleFromDepth(bestDepth) + << "bit window depth for" << nsWindow; + + nsWindow.depthLimit = bestDepth; } QNSWindowBackingStore::~QNSWindowBackingStore() diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 3008a056a2..a3120f4ccc 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1659,21 +1659,6 @@ QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBePanel) applyContentBorderThickness(nsWindow); - // Prevent CoreGraphics RGB32 -> RGB64 backing store conversions on deep color - // displays by forcing 8-bit components, unless a deep color format has been - // requested. This conversion uses significant CPU time. - QSurface::SurfaceType surfaceType = QPlatformWindow::window()->surfaceType(); - bool usesCoreGraphics = surfaceType == QSurface::RasterSurface || surfaceType == QSurface::RasterGLSurface; - QSurfaceFormat surfaceFormat = QPlatformWindow::window()->format(); - bool usesDeepColor = surfaceFormat.redBufferSize() > 8 || - surfaceFormat.greenBufferSize() > 8 || - surfaceFormat.blueBufferSize() > 8; - bool usesLayer = view().layer; - if (usesCoreGraphics && !usesDeepColor && !usesLayer) { - [nsWindow setDynamicDepthLimit:NO]; - [nsWindow setDepthLimit:NSWindowDepthTwentyfourBitRGB]; - } - if (format().colorSpace() == QSurfaceFormat::sRGBColorSpace) nsWindow.colorSpace = NSColorSpace.sRGBColorSpace; -- cgit v1.2.3 From 29b1ac069721e3ebfd883685c9dce0524125ec39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 31 Jul 2019 14:10:56 +0200 Subject: Don't defer platform backingstore creation if we already have a platform window The creation was made lazy in 18f415e46d592f, for those platforms (macOS) that need a platform window to successfully create a platform backingstore. But we don't need to delay creation if we actually have a platform window at the time of constructing the QBackingStore. Change-Id: I6367736ddca82900dec2751a85a8bc35cc742bb5 Reviewed-by: Volker Hilsheimer Reviewed-by: Lars Knoll Reviewed-by: Timur Pocheptsov --- src/gui/painting/qbackingstore.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp index b9ed3d4995..f86dfbfba1 100644 --- a/src/gui/painting/qbackingstore.cpp +++ b/src/gui/painting/qbackingstore.cpp @@ -95,6 +95,11 @@ public: QBackingStore::QBackingStore(QWindow *window) : d_ptr(new QBackingStorePrivate(window)) { + if (window->handle()) { + // Create platform backingstore up front if we have a platform window, + // otherwise delay the creation until absolutely necessary. + handle(); + } } /*! -- cgit v1.2.3 From b3dc0c13e88f3bd859c96144a9d4280c675665bc Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 24 Aug 2019 06:47:41 +0200 Subject: Fix assertion on passing nullptr QLatin1Strings to qt_compare_strings qstrnicmp() has an assertion that the lhs string is not nullptr. Fix by moving the length check back to the front, regardless of cs's value. Amends cad7100fda1b27ba56c4d9efc6bceba62859dfbc. Change-Id: I31f808936c8dc6fbb10a70a59923746ef3e675e9 Reviewed-by: Thiago Macieira --- src/corelib/tools/qstring.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 4852d20082..ad2e8bbcd8 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -1199,10 +1199,10 @@ static int qt_compare_strings(QLatin1String lhs, QStringView rhs, Qt::CaseSensit static int qt_compare_strings(QLatin1String lhs, QLatin1String rhs, Qt::CaseSensitivity cs) Q_DECL_NOTHROW { - if (cs == Qt::CaseInsensitive) - return qstrnicmp(lhs.data(), lhs.size(), rhs.data(), rhs.size()); if (lhs.isEmpty()) return lencmp(0, rhs.size()); + if (cs == Qt::CaseInsensitive) + return qstrnicmp(lhs.data(), lhs.size(), rhs.data(), rhs.size()); const auto l = std::min(lhs.size(), rhs.size()); int r = qstrncmp(lhs.data(), rhs.data(), l); return r ? r : lencmp(lhs.size(), rhs.size()); -- cgit v1.2.3