diff options
44 files changed, 933 insertions, 405 deletions
diff --git a/mkspecs/wasm-emscripten/qmake.conf b/mkspecs/wasm-emscripten/qmake.conf index 992803e055..c69ed9af79 100644 --- a/mkspecs/wasm-emscripten/qmake.conf +++ b/mkspecs/wasm-emscripten/qmake.conf @@ -28,6 +28,7 @@ EMTERP_FLAGS = \ EMCC_COMMON_LFLAGS = \ -s WASM=1 \ -s FULL_ES2=1 \ + -s FULL_ES3=1 \ -s USE_WEBGL2=1 \ -s NO_EXIT_RUNTIME=0 \ -s ERROR_ON_UNDEFINED_SYMBOLS=1 \ diff --git a/src/corelib/text/qchar.cpp b/src/corelib/text/qchar.cpp index 9b03a93278..847b4f0b08 100644 --- a/src/corelib/text/qchar.cpp +++ b/src/corelib/text/qchar.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -189,6 +189,9 @@ QT_BEGIN_NAMESPACE \value Unicode_8_0 Version 8.0 Since Qt 5.6 \value Unicode_9_0 Version 9.0 Since Qt 5.11 \value Unicode_10_0 Version 10.0 Since Qt 5.11 + \value Unicode_11_0 Version 11.0 Since Qt 5.15 + \value Unicode_12_0 Version 12.0 Since Qt 5.15 + \value Unicode_12_1 Version 12.1 Since Qt 5.15 \value Unicode_Unassigned The value is not assigned to any character in version 8.0 of Unicode. @@ -288,145 +291,156 @@ QT_BEGIN_NAMESPACE \value Script_Common For characters that may be used with multiple scripts and that do not inherit their script from the preceding characters. - \value Script_Latin - \value Script_Greek - \value Script_Cyrillic - \value Script_Armenian - \value Script_Hebrew + \value Script_Adlam Since Qt 5.11 + \value Script_Ahom Since Qt 5.6 + \value Script_AnatolianHieroglyphs Since Qt 5.6 \value Script_Arabic - \value Script_Syriac - \value Script_Thaana - \value Script_Devanagari + \value Script_Armenian + \value Script_Avestan + \value Script_Balinese + \value Script_Bamum + \value Script_BassaVah Since Qt 5.5 + \value Script_Batak \value Script_Bengali - \value Script_Gurmukhi - \value Script_Gujarati - \value Script_Oriya - \value Script_Tamil - \value Script_Telugu - \value Script_Kannada - \value Script_Malayalam - \value Script_Sinhala - \value Script_Thai - \value Script_Lao - \value Script_Tibetan - \value Script_Myanmar - \value Script_Georgian - \value Script_Hangul - \value Script_Ethiopic - \value Script_Cherokee - \value Script_CanadianAboriginal - \value Script_Ogham - \value Script_Runic - \value Script_Khmer - \value Script_Mongolian - \value Script_Hiragana - \value Script_Katakana + \value Script_Bhaiksuki Since Qt 5.11 \value Script_Bopomofo - \value Script_Han - \value Script_Yi - \value Script_OldItalic - \value Script_Gothic - \value Script_Deseret - \value Script_Tagalog - \value Script_Hanunoo - \value Script_Buhid - \value Script_Tagbanwa - \value Script_Coptic - \value Script_Limbu - \value Script_TaiLe - \value Script_LinearB - \value Script_Ugaritic - \value Script_Shavian - \value Script_Osmanya - \value Script_Cypriot + \value Script_Brahmi \value Script_Braille \value Script_Buginese - \value Script_NewTaiLue - \value Script_Glagolitic - \value Script_Tifinagh - \value Script_SylotiNagri - \value Script_OldPersian - \value Script_Kharoshthi - \value Script_Balinese - \value Script_Cuneiform - \value Script_Phoenician - \value Script_PhagsPa - \value Script_Nko - \value Script_Sundanese - \value Script_Lepcha - \value Script_OlChiki - \value Script_Vai - \value Script_Saurashtra - \value Script_KayahLi - \value Script_Rejang - \value Script_Lycian + \value Script_Buhid + \value Script_CanadianAboriginal \value Script_Carian - \value Script_Lydian + \value Script_CaucasianAlbanian Since Qt 5.5 + \value Script_Chakma \value Script_Cham - \value Script_TaiTham - \value Script_TaiViet - \value Script_Avestan + \value Script_Cherokee + \value Script_Coptic + \value Script_Cuneiform + \value Script_Cypriot + \value Script_Cyrillic + \value Script_Deseret + \value Script_Devanagari + \value Script_Dogra Since Qt 5.15 + \value Script_Duployan Since Qt 5.5 \value Script_EgyptianHieroglyphs - \value Script_Samaritan - \value Script_Lisu - \value Script_Bamum - \value Script_Javanese - \value Script_MeeteiMayek + \value Script_Elbasan Since Qt 5.5 + \value Script_Elymaic Since Qt 5.15 + \value Script_Ethiopic + \value Script_Georgian + \value Script_Glagolitic + \value Script_Gothic + \value Script_Grantha Since Qt 5.5 + \value Script_Greek + \value Script_Gujarati + \value Script_GunjalaGondi Since Qt 5.15 + \value Script_Gurmukhi + \value Script_Han + \value Script_Hangul + \value Script_HanifiRohingya Since Qt 5.15 + \value Script_Hanunoo + \value Script_Hatran Since Qt 5.6 + \value Script_Hebrew + \value Script_Hiragana \value Script_ImperialAramaic - \value Script_OldSouthArabian - \value Script_InscriptionalParthian \value Script_InscriptionalPahlavi - \value Script_OldTurkic + \value Script_InscriptionalParthian + \value Script_Javanese \value Script_Kaithi - \value Script_Batak - \value Script_Brahmi + \value Script_Kannada + \value Script_Katakana + \value Script_KayahLi + \value Script_Kharoshthi + \value Script_Khmer + \value Script_Khojki Since Qt 5.5 + \value Script_Khudawadi Since Qt 5.5 + \value Script_Lao + \value Script_Latin + \value Script_Lepcha + \value Script_Limbu + \value Script_LinearA Since Qt 5.5 + \value Script_LinearB + \value Script_Lisu + \value Script_Lycian + \value Script_Lydian + \value Script_Mahajani Since Qt 5.5 + \value Script_Makasar Since Qt 5.15 + \value Script_Malayalam \value Script_Mandaic - \value Script_Chakma + \value Script_Manichaean Since Qt 5.5 + \value Script_Marchen Since Qt 5.11 + \value Script_MasaramGondi Since Qt 5.11 + \value Script_Medefaidrin Since Qt 5.15 + \value Script_MeeteiMayek + \value Script_MendeKikakui Since Qt 5.5 \value Script_MeroiticCursive \value Script_MeroiticHieroglyphs \value Script_Miao + \value Script_Modi Since Qt 5.5 + \value Script_Mongolian + \value Script_Mro Since Qt 5.5 + \value Script_Multani Since Qt 5.6 + \value Script_Myanmar + \value Script_Nabataean Since Qt 5.5 + \value Script_Nandinagari Since Qt 5.15 + \value Script_Newa Since Qt 5.11 + \value Script_NewTaiLue + \value Script_Nko + \value Script_Nushu Since Qt 5.11 + \value Script_NyiakengPuachueHmong Since Qt 5.15 + \value Script_Ogham + \value Script_OlChiki + \value Script_OldHungarian Since Qt 5.6 + \value Script_OldItalic + \value Script_OldNorthArabian Since Qt 5.5 + \value Script_OldPermic Since Qt 5.5 + \value Script_OldPersian + \value Script_OldSogdian Since Qt 5.15 + \value Script_OldSouthArabian + \value Script_OldTurkic + \value Script_Oriya + \value Script_Osage Since Qt 5.11 + \value Script_Osmanya + \value Script_PahawhHmong Since Qt 5.5 + \value Script_Palmyrene Since Qt 5.5 + \value Script_PauCinHau Since Qt 5.5 + \value Script_PhagsPa + \value Script_Phoenician + \value Script_PsalterPahlavi Since Qt 5.5 + \value Script_Rejang + \value Script_Runic + \value Script_Samaritan + \value Script_Saurashtra \value Script_Sharada + \value Script_Shavian + \value Script_Siddham Since Qt 5.5 + \value Script_SignWriting Since Qt 5.6 + \value Script_Sinhala + \value Script_Sogdian Since Qt 5.15 \value Script_SoraSompeng + \value Script_Soyombo Since Qt 5.11 + \value Script_Sundaneseo + \value Script_SylotiNagri + \value Script_Syriac + \value Script_Tagalog + \value Script_Tagbanwa + \value Script_TaiLe + \value Script_TaiTham + \value Script_TaiViet \value Script_Takri - \value Script_CaucasianAlbanian - \value Script_BassaVah - \value Script_Duployan - \value Script_Elbasan - \value Script_Grantha - \value Script_PahawhHmong - \value Script_Khojki - \value Script_LinearA - \value Script_Mahajani - \value Script_Manichaean - \value Script_MendeKikakui - \value Script_Modi - \value Script_Mro - \value Script_OldNorthArabian - \value Script_Nabataean - \value Script_Palmyrene - \value Script_PauCinHau - \value Script_OldPermic - \value Script_PsalterPahlavi - \value Script_Siddham - \value Script_Khudawadi - \value Script_Tirhuta - \value Script_WarangCiti - \value Script_Ahom - \value Script_AnatolianHieroglyphs - \value Script_Hatran - \value Script_Multani - \value Script_OldHungarian - \value Script_SignWriting - \value Script_Adlam - \value Script_Bhaiksuki - \value Script_Marchen - \value Script_Newa - \value Script_Osage - \value Script_Tangut - \value Script_MasaramGondi - \value Script_Nushu - \value Script_Soyombo - \value Script_ZanabazarSquare + \value Script_Tamil + \value Script_Tangut Since Qt 5.11 + \value Script_Telugu + \value Script_Thaana + \value Script_Thai + \value Script_Tibetan + \value Script_Tifinagh + \value Script_Tirhuta Since Qt 5.5 + \value Script_Ugaritic + \value Script_Vai + \value Script_Wancho Since Qt 5.15 + \value Script_WarangCiti Since Qt 5.5 + \value Script_Yi + \value Script_ZanabazarSquare Since Qt 5.11 \omitvalue ScriptCount diff --git a/src/corelib/text/qchar.h b/src/corelib/text/qchar.h index 85a380e7cf..a3d5d7a65e 100644 --- a/src/corelib/text/qchar.h +++ b/src/corelib/text/qchar.h @@ -437,7 +437,7 @@ public: Unicode_10_0, Unicode_11_0, Unicode_12_0, - Unicode_12_1, + Unicode_12_1 }; // ****** WHEN ADDING FUNCTIONS, CONSIDER ADDING TO QCharRef TOO diff --git a/src/corelib/text/qunicodetables_p.h b/src/corelib/text/qunicodetables_p.h index 79878a859f..81efc09773 100644 --- a/src/corelib/text/qunicodetables_p.h +++ b/src/corelib/text/qunicodetables_p.h @@ -122,7 +122,8 @@ enum GraphemeBreakClass { Graphemebreak_E_Modifier, Graphemebreak_Glue_After_Zwj, Graphemebreak_E_Base_GAZ, - NumGraphemeBreakClasses, + + NumGraphemeBreakClasses }; enum WordBreakClass { @@ -149,7 +150,8 @@ enum WordBreakClass { WordBreak_Glue_After_Zwj, WordBreak_E_Base_GAZ, WordBreak_WSegSpace, - NumWordBreakClasses, + + NumWordBreakClasses }; enum SentenceBreakClass { @@ -167,6 +169,7 @@ enum SentenceBreakClass { SentenceBreak_SContinue, SentenceBreak_STerm, SentenceBreak_Close, + NumSentenceBreakClasses }; @@ -182,6 +185,7 @@ enum LineBreakClass { LineBreak_EB, LineBreak_EM, LineBreak_ZWJ, LineBreak_SA, LineBreak_SG, LineBreak_SP, LineBreak_CR, LineBreak_LF, LineBreak_BK, + NumLineBreakClasses }; diff --git a/src/gui/configure.json b/src/gui/configure.json index 3478f51902..3891ff4070 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -1315,7 +1315,7 @@ }, "opengles3": { "label": "OpenGL ES 3.0", - "condition": "features.opengles2 && !features.angle && tests.opengles3 && !config.wasm", + "condition": "features.opengles2 && !features.angle && tests.opengles3", "output": [ "publicFeature", { "type": "define", "name": "QT_OPENGL_ES_3" } diff --git a/src/gui/kernel/qshortcutmap.cpp b/src/gui/kernel/qshortcutmap.cpp index b5cd342138..1d244d97e8 100644 --- a/src/gui/kernel/qshortcutmap.cpp +++ b/src/gui/kernel/qshortcutmap.cpp @@ -45,13 +45,13 @@ #include "qvector.h" #include "qcoreapplication.h" #include <private/qkeymapper_p.h> +#include <QtCore/qloggingcategory.h> #include <algorithm> QT_BEGIN_NAMESPACE -// To enable verbose output uncomment below -//#define DEBUG_QSHORTCUTMAP +Q_LOGGING_CATEGORY(lcShortcutMap, "qt.gui.shortcutmap") /* \internal Entry data for QShortcutMap @@ -163,11 +163,9 @@ int QShortcutMap::addShortcut(QObject *owner, const QKeySequence &key, Qt::Short QShortcutEntry newEntry(owner, key, context, --(d->currentId), true, matcher); const auto it = std::upper_bound(d->sequences.begin(), d->sequences.end(), newEntry); d->sequences.insert(it, newEntry); // Insert sorted -#if defined(DEBUG_QSHORTCUTMAP) - qDebug().nospace() + qCDebug(lcShortcutMap).nospace() << "QShortcutMap::addShortcut(" << owner << ", " << key << ", " << context << ") = " << d->currentId; -#endif return d->currentId; } @@ -210,11 +208,9 @@ int QShortcutMap::removeShortcut(int id, QObject *owner, const QKeySequence &key return itemsRemoved; --i; } -#if defined(DEBUG_QSHORTCUTMAP) - qDebug().nospace() + qCDebug(lcShortcutMap).nospace() << "QShortcutMap::removeShortcut(" << id << ", " << owner << ", " << key << ") = " << itemsRemoved; -#endif return itemsRemoved; } @@ -248,11 +244,9 @@ int QShortcutMap::setShortcutEnabled(bool enable, int id, QObject *owner, const return itemsChanged; --i; } -#if defined(DEBUG_QSHORTCUTMAP) - qDebug().nospace() + qCDebug(lcShortcutMap).nospace() << "QShortcutMap::setShortcutEnabled(" << enable << ", " << id << ", " << owner << ", " << key << ") = " << itemsChanged; -#endif return itemsChanged; } @@ -286,11 +280,9 @@ int QShortcutMap::setShortcutAutoRepeat(bool on, int id, QObject *owner, const Q return itemsChanged; --i; } -#if defined(DEBUG_QSHORTCUTMAP) - qDebug().nospace() + qCDebug(lcShortcutMap).nospace() << "QShortcutMap::setShortcutAutoRepeat(" << on << ", " << id << ", " << owner << ", " << key << ") = " << itemsChanged; -#endif return itemsChanged; } @@ -393,9 +385,7 @@ QKeySequence::SequenceMatch QShortcutMap::nextState(QKeyEvent *e) clearSequence(d->currentSequences); d->currentState = result; -#if defined(DEBUG_QSHORTCUTMAP) - qDebug().nospace() << "QShortcutMap::nextState(" << e << ") = " << result; -#endif + qCDebug(lcShortcutMap).nospace() << "QShortcutMap::nextState(" << e << ") = " << result; return result; } @@ -434,9 +424,7 @@ QKeySequence::SequenceMatch QShortcutMap::find(QKeyEvent *e, int ignoredModifier return QKeySequence::NoMatch; createNewSequences(e, d->newEntries, ignoredModifiers); -#if defined(DEBUG_QSHORTCUTMAP) - qDebug() << "Possible shortcut key sequences:" << d->newEntries; -#endif + qCDebug(lcShortcutMap) << "Possible shortcut key sequences:" << d->newEntries; // Should never happen if (d->newEntries == d->currentSequences) { @@ -489,15 +477,11 @@ QKeySequence::SequenceMatch QShortcutMap::find(QKeyEvent *e, int ignoredModifier // previous list. If this match is equal or better than the last match, append to the list if (oneKSResult > result) { okEntries.clear(); -#if defined(DEBUG_QSHORTCUTMAP) - qDebug() << "Found better match (" << d->newEntries << "), clearing key sequence list"; -#endif + qCDebug(lcShortcutMap) << "Found better match (" << d->newEntries << "), clearing key sequence list"; } if (oneKSResult && oneKSResult >= result) { okEntries << d->newEntries.at(i); -#if defined(DEBUG_QSHORTCUTMAP) - qDebug() << "Added ok key sequence" << d->newEntries; -#endif + qCDebug(lcShortcutMap) << "Added ok key sequence" << d->newEntries; } } @@ -513,9 +497,7 @@ QKeySequence::SequenceMatch QShortcutMap::find(QKeyEvent *e, int ignoredModifier } if (result != QKeySequence::NoMatch) d->currentSequences = okEntries; -#if defined(DEBUG_QSHORTCUTMAP) - qDebug() << "Returning shortcut match == " << result; -#endif + qCDebug(lcShortcutMap) << "Returning shortcut match == " << result; return QKeySequence::SequenceMatch(result); } @@ -538,19 +520,16 @@ void QShortcutMap::createNewSequences(QKeyEvent *e, QVector<QKeySequence> &ksl, { Q_D(QShortcutMap); QList<int> possibleKeys = QKeyMapper::possibleKeys(e); -#if defined(DEBUG_QSHORTCUTMAP) - { - QDebug debug = qDebug().nospace(); - debug << __FUNCTION__ << '(' << e << ", ignoredModifiers=" + if (lcShortcutMap().isDebugEnabled()) { + qCDebug(lcShortcutMap).nospace() << __FUNCTION__ << '(' << e << ", ignoredModifiers=" << Qt::KeyboardModifiers(ignoredModifiers) << "), possibleKeys=("; for (int i = 0, size = possibleKeys.size(); i < size; ++i) { if (i) - debug << ", "; - debug << QKeySequence(possibleKeys.at(i)); + qCDebug(lcShortcutMap).nospace() << ", "; + qCDebug(lcShortcutMap).nospace() << QKeySequence(possibleKeys.at(i)); } - debug << ')'; + qCDebug(lcShortcutMap).nospace() << ')'; } -#endif // DEBUG_QSHORTCUTMAP int pkTotal = possibleKeys.count(); if (!pkTotal) return; @@ -659,16 +638,13 @@ void QShortcutMap::dispatchEvent(QKeyEvent *e) // Find next const QShortcutEntry *current = 0, *next = 0; int i = 0, enabledShortcuts = 0; -#if defined(DEBUG_QSHORTCUTMAP) QVector<const QShortcutEntry*> ambiguousShortcuts; -#endif while(i < d->identicals.size()) { current = d->identicals.at(i); if (current->enabled || !next){ ++enabledShortcuts; -#if defined(DEBUG_QSHORTCUTMAP) - ambiguousShortcuts.append(current); -#endif + if (lcShortcutMap().isDebugEnabled()) + ambiguousShortcuts.append(current); if (enabledShortcuts > d->ambigCount + 1) break; next = current; @@ -681,19 +657,18 @@ void QShortcutMap::dispatchEvent(QKeyEvent *e) if (!next || (e->isAutoRepeat() && !next->autorepeat)) return; // Dispatch next enabled -#if defined(DEBUG_QSHORTCUTMAP) - if (ambiguousShortcuts.size() > 1) { - qDebug() << "The following shortcuts are about to be activated ambiguously:"; - for (const QShortcutEntry *entry : qAsConst(ambiguousShortcuts)) { - qDebug().nospace() << "- " << entry->keyseq << " (belonging to " << entry->owner << ")"; + if (lcShortcutMap().isDebugEnabled()) { + if (ambiguousShortcuts.size() > 1) { + qCDebug(lcShortcutMap) << "The following shortcuts are about to be activated ambiguously:"; + for (const QShortcutEntry *entry : qAsConst(ambiguousShortcuts)) + qCDebug(lcShortcutMap).nospace() << "- " << entry->keyseq << " (belonging to " << entry->owner << ")"; } - } - qDebug().nospace() - << "QShortcutMap::dispatchEvent(): Sending QShortcutEvent(\"" - << next->keyseq.toString() << "\", " << next->id << ", " - << (bool)(enabledShortcuts>1) << ") to object(" << next->owner << ')'; -#endif + qCDebug(lcShortcutMap).nospace() + << "QShortcutMap::dispatchEvent(): Sending QShortcutEvent(\"" + << next->keyseq.toString() << "\", " << next->id << ", " + << static_cast<bool>(enabledShortcuts>1) << ") to object(" << next->owner << ')'; + } QShortcutEvent se(next->keyseq, next->id, enabledShortcuts>1); QCoreApplication::sendEvent(const_cast<QObject *>(next->owner), &se); } diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp index 8ef98d2e42..ece5190ff7 100644 --- a/src/gui/rhi/qrhi.cpp +++ b/src/gui/rhi/qrhi.cpp @@ -48,8 +48,7 @@ #ifdef Q_OS_WIN #include "qrhid3d11_p_p.h" #endif -//#ifdef Q_OS_DARWIN -#ifdef Q_OS_MACOS +#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) #include "qrhimetal_p_p.h" #endif @@ -2253,9 +2252,7 @@ bool QRhiTexture::buildFrom(const QRhiNativeHandles *src) \value Repeat \value ClampToEdge - \value Border \value Mirror - \value MirrorOnce */ /*! @@ -2322,6 +2319,24 @@ QRhiResource::Type QRhiRenderPassDescriptor::resourceType() const } /*! + \fn bool QRhiRenderPassDescriptor::isCompatible(const QRhiRenderPassDescriptor *other) const; + + \return true if the \a other QRhiRenderPassDescriptor is compatible with + this one, meaning \c this and \a other can be used interchangebly in + QRhiGraphicsPipeline::setRenderPassDescriptor(). + + The concept of the compatibility of renderpass descriptors is similar to + the \l{QRhiShaderResourceBindings::isLayoutCompatible}{layout + compatibility} of QRhiShaderResourceBindings instances. They allow better + reuse of QRhiGraphicsPipeline instances: for example, a + QRhiGraphicsPipeline instance cache is expected to use these functions to + look for a matching pipeline, instead of just comparing pointers, thus + allowing a different QRhiRenderPassDescriptor and + QRhiShaderResourceBindings to be used in combination with the pipeline, as + long as they are compatible. + */ + +/*! \return a pointer to a backend-specific QRhiNativeHandles subclass, such as QRhiVulkanRenderPassNativeHandles. The returned value is null when exposing the underlying native resources is not supported by the backend. @@ -4049,8 +4064,7 @@ QRhi *QRhi::create(Implementation impl, QRhiInitParams *params, Flags flags, QRh break; #endif case Metal: -//#ifdef Q_OS_DARWIN -#ifdef Q_OS_MACOS +#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) r->d = new QRhiMetal(static_cast<QRhiMetalInitParams *>(params), static_cast<QRhiMetalNativeHandles *>(importDevice)); break; diff --git a/src/gui/rhi/qrhi_p.h b/src/gui/rhi/qrhi_p.h index 907924c788..9df2c58962 100644 --- a/src/gui/rhi/qrhi_p.h +++ b/src/gui/rhi/qrhi_p.h @@ -812,9 +812,7 @@ public: enum AddressMode { Repeat, ClampToEdge, - Border, Mirror, - MirrorOnce }; enum CompareOp { @@ -913,6 +911,7 @@ class Q_GUI_EXPORT QRhiRenderPassDescriptor : public QRhiResource public: QRhiResource::Type resourceType() const override; + virtual bool isCompatible(const QRhiRenderPassDescriptor *other) const = 0; virtual const QRhiNativeHandles *nativeHandles(); protected: diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp index 5e576e9c6a..52109edce0 100644 --- a/src/gui/rhi/qrhid3d11.cpp +++ b/src/gui/rhi/qrhid3d11.cpp @@ -2862,12 +2862,8 @@ static inline D3D11_TEXTURE_ADDRESS_MODE toD3DAddressMode(QRhiSampler::AddressMo return D3D11_TEXTURE_ADDRESS_WRAP; case QRhiSampler::ClampToEdge: return D3D11_TEXTURE_ADDRESS_CLAMP; - case QRhiSampler::Border: - return D3D11_TEXTURE_ADDRESS_BORDER; case QRhiSampler::Mirror: return D3D11_TEXTURE_ADDRESS_MIRROR; - case QRhiSampler::MirrorOnce: - return D3D11_TEXTURE_ADDRESS_MIRROR_ONCE; default: Q_UNREACHABLE(); return D3D11_TEXTURE_ADDRESS_CLAMP; @@ -2944,6 +2940,12 @@ void QD3D11RenderPassDescriptor::release() // nothing to do here } +bool QD3D11RenderPassDescriptor::isCompatible(const QRhiRenderPassDescriptor *other) const +{ + Q_UNUSED(other); + return true; +} + QD3D11ReferenceRenderTarget::QD3D11ReferenceRenderTarget(QRhiImplementation *rhi) : QRhiRenderTarget(rhi), d(rhi) diff --git a/src/gui/rhi/qrhid3d11_p_p.h b/src/gui/rhi/qrhid3d11_p_p.h index 26de34ae0a..13c56b1d6d 100644 --- a/src/gui/rhi/qrhid3d11_p_p.h +++ b/src/gui/rhi/qrhid3d11_p_p.h @@ -136,6 +136,7 @@ struct QD3D11RenderPassDescriptor : public QRhiRenderPassDescriptor QD3D11RenderPassDescriptor(QRhiImplementation *rhi); ~QD3D11RenderPassDescriptor(); void release() override; + bool isCompatible(const QRhiRenderPassDescriptor *other) const override; }; struct QD3D11RenderTargetData diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp index abee843a74..b0e9a149f1 100644 --- a/src/gui/rhi/qrhigles2.cpp +++ b/src/gui/rhi/qrhigles2.cpp @@ -1785,11 +1785,6 @@ static inline GLenum toGlWrapMode(QRhiSampler::AddressMode m) return GL_CLAMP_TO_EDGE; case QRhiSampler::Mirror: return GL_MIRRORED_REPEAT; - case QRhiSampler::MirrorOnce: - Q_FALLTHROUGH(); - case QRhiSampler::Border: - qWarning("Unsupported wrap mode %d", m); - return GL_CLAMP_TO_EDGE; default: Q_UNREACHABLE(); return GL_CLAMP_TO_EDGE; @@ -3460,6 +3455,12 @@ void QGles2RenderPassDescriptor::release() // nothing to do here } +bool QGles2RenderPassDescriptor::isCompatible(const QRhiRenderPassDescriptor *other) const +{ + Q_UNUSED(other); + return true; +} + QGles2ReferenceRenderTarget::QGles2ReferenceRenderTarget(QRhiImplementation *rhi) : QRhiRenderTarget(rhi), d(rhi) diff --git a/src/gui/rhi/qrhigles2_p_p.h b/src/gui/rhi/qrhigles2_p_p.h index cc945876e6..b0f5e340fb 100644 --- a/src/gui/rhi/qrhigles2_p_p.h +++ b/src/gui/rhi/qrhigles2_p_p.h @@ -185,6 +185,7 @@ struct QGles2RenderPassDescriptor : public QRhiRenderPassDescriptor QGles2RenderPassDescriptor(QRhiImplementation *rhi); ~QGles2RenderPassDescriptor(); void release() override; + bool isCompatible(const QRhiRenderPassDescriptor *other) const override; }; struct QGles2RenderTargetData diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm index 131b2da802..e5af1cfab1 100644 --- a/src/gui/rhi/qrhimetal.mm +++ b/src/gui/rhi/qrhimetal.mm @@ -41,6 +41,8 @@ #ifdef Q_OS_MACOS #include <AppKit/AppKit.h> +#else +#include <UIKit/UIKit.h> #endif #include <Metal/Metal.h> @@ -318,7 +320,13 @@ struct QMetalComputePipelineData struct QMetalSwapChainData { + // The iOS simulator's headers mark CAMetalLayer as iOS 13.0+ only. + // (for real device SDKs it is 8.0+) +#ifdef TARGET_IPHONE_SIMULATOR + API_AVAILABLE(ios(13.0)) CAMetalLayer *layer = nullptr; +#else CAMetalLayer *layer = nullptr; +#endif id<CAMetalDrawable> curDrawable; dispatch_semaphore_t sem[QMTL_FRAMES_IN_FLIGHT]; MTLRenderPassDescriptor *rp = nullptr; @@ -1763,8 +1771,10 @@ void QRhiMetal::executeBufferHostWritesForCurrentFrame(QMetalBuffer *bufD) if (changeEnd == -1 || u.offset + u.data.size() > changeEnd) changeEnd = u.offset + u.data.size(); } +#ifdef Q_OS_MACOS if (changeBegin >= 0 && bufD->d->managed) [bufD->d->buf[idx] didModifyRange: NSMakeRange(NSUInteger(changeBegin), NSUInteger(changeEnd - changeBegin))]; +#endif bufD->d->pendingUpdates[idx].clear(); } @@ -1798,8 +1808,12 @@ void QRhiMetal::beginPass(QRhiCommandBuffer *cb, if (color0.needsDrawableForTex || color0.needsDrawableForResolveTex) { Q_ASSERT(currentSwapChain); QMetalSwapChain *swapChainD = QRHI_RES(QMetalSwapChain, currentSwapChain); - if (!swapChainD->d->curDrawable) - swapChainD->d->curDrawable = [swapChainD->d->layer nextDrawable]; + if (!swapChainD->d->curDrawable) { +#ifdef TARGET_IPHONE_SIMULATOR + if (@available(ios 13.0, *)) +#endif + swapChainD->d->curDrawable = [swapChainD->d->layer nextDrawable]; + } if (!swapChainD->d->curDrawable) { qWarning("No drawable"); return; @@ -2170,12 +2184,13 @@ bool QMetalRenderBuffer::build() case DepthStencil: #ifdef Q_OS_MACOS desc.storageMode = MTLStorageModePrivate; + d->format = rhiD->d->dev.depth24Stencil8PixelFormatSupported + ? MTLPixelFormatDepth24Unorm_Stencil8 : MTLPixelFormatDepth32Float_Stencil8; #else - desc.storageMode = MTLResourceStorageModeMemoryless; + desc.storageMode = MTLStorageModeMemoryless; transientBacking = true; + d->format = MTLPixelFormatDepth32Float_Stencil8; #endif - d->format = rhiD->d->dev.depth24Stencil8PixelFormatSupported - ? MTLPixelFormatDepth24Unorm_Stencil8 : MTLPixelFormatDepth32Float_Stencil8; desc.pixelFormat = d->format; break; case Color: @@ -2569,12 +2584,8 @@ static inline MTLSamplerAddressMode toMetalAddressMode(QRhiSampler::AddressMode return MTLSamplerAddressModeRepeat; case QRhiSampler::ClampToEdge: return MTLSamplerAddressModeClampToEdge; - case QRhiSampler::Border: - return MTLSamplerAddressModeClampToBorderColor; case QRhiSampler::Mirror: return MTLSamplerAddressModeMirrorRepeat; - case QRhiSampler::MirrorOnce: - return MTLSamplerAddressModeMirrorClampToEdge; default: Q_UNREACHABLE(); return MTLSamplerAddressModeClampToEdge; @@ -2647,6 +2658,32 @@ void QMetalRenderPassDescriptor::release() // nothing to do here } +bool QMetalRenderPassDescriptor::isCompatible(const QRhiRenderPassDescriptor *other) const +{ + if (!other) + return false; + + const QMetalRenderPassDescriptor *o = QRHI_RES(const QMetalRenderPassDescriptor, other); + + if (colorAttachmentCount != o->colorAttachmentCount) + return false; + + if (hasDepthStencil != o->hasDepthStencil) + return false; + + for (int i = 0; i < colorAttachmentCount; ++i) { + if (colorFormat[i] != o->colorFormat[i]) + return false; + } + + if (hasDepthStencil) { + if (dsFormat != o->dsFormat) + return false; + } + + return true; +} + QMetalReferenceRenderTarget::QMetalReferenceRenderTarget(QRhiImplementation *rhi) : QRhiRenderTarget(rhi), d(new QMetalRenderTargetData) @@ -3311,7 +3348,11 @@ bool QMetalGraphicsPipeline::build() // validation blows up otherwise. MTLPixelFormat fmt = MTLPixelFormat(rpD->dsFormat); rpDesc.depthAttachmentPixelFormat = fmt; +#ifdef Q_OS_MACOS if (fmt != MTLPixelFormatDepth16Unorm && fmt != MTLPixelFormatDepth32Float) +#else + if (fmt != MTLPixelFormatDepth32Float) +#endif rpDesc.stencilAttachmentPixelFormat = fmt; } @@ -3528,6 +3569,10 @@ QMetalSwapChain::~QMetalSwapChain() void QMetalSwapChain::release() { +#ifdef TARGET_IPHONE_SIMULATOR + if (@available(ios 13.0, *)) { +#endif + if (!d->layer) return; @@ -3556,6 +3601,10 @@ void QMetalSwapChain::release() QRHI_PROF_F(releaseSwapChain(this)); rhiD->unregisterResource(this); + +#ifdef TARGET_IPHONE_SIMULATOR + } +#endif } QRhiCommandBuffer *QMetalSwapChain::currentFrameCommandBuffer() @@ -3578,16 +3627,20 @@ QRhiRenderPassDescriptor *QMetalSwapChain::newCompatibleRenderPassDescriptor() { chooseFormats(); // ensure colorFormat and similar are filled out - QRHI_RES_RHI(QRhiMetal); QMetalRenderPassDescriptor *rpD = new QMetalRenderPassDescriptor(m_rhi); rpD->colorAttachmentCount = 1; rpD->hasDepthStencil = m_depthStencil != nullptr; rpD->colorFormat[0] = int(d->colorFormat); +#ifdef Q_OS_MACOS // m_depthStencil may not be built yet so cannot rely on computed fields in it + QRHI_RES_RHI(QRhiMetal); rpD->dsFormat = rhiD->d->dev.depth24Stencil8PixelFormatSupported ? MTLPixelFormatDepth24Unorm_Stencil8 : MTLPixelFormatDepth32Float_Stencil8; +#else + rpD->dsFormat = MTLPixelFormatDepth32Float_Stencil8; +#endif return rpD; } @@ -3603,6 +3656,10 @@ void QMetalSwapChain::chooseFormats() bool QMetalSwapChain::buildOrResize() { +#ifdef TARGET_IPHONE_SIMULATOR + if (@available(ios 13.0, *)) { +#endif + Q_ASSERT(m_window); const bool needsRegistration = !window || window != m_window; @@ -3622,7 +3679,11 @@ bool QMetalSwapChain::buildOrResize() return false; } +#ifdef Q_OS_MACOS NSView *view = reinterpret_cast<NSView *>(window->winId()); +#else + UIView *view = reinterpret_cast<UIView *>(window->winId()); +#endif Q_ASSERT(view); d->layer = static_cast<CAMetalLayer *>(view.layer); Q_ASSERT(d->layer); @@ -3726,6 +3787,15 @@ bool QMetalSwapChain::buildOrResize() rhiD->registerResource(this); return true; + +#ifdef TARGET_IPHONE_SIMULATOR + } else { + // Won't ever get here in a normal app because MTLDevice creation would + // fail too. Print a warning, just in case. + qWarning("No CAMetalLayer support in this version of the iOS Simulator"); + return false; + } +#endif } QT_END_NAMESPACE diff --git a/src/gui/rhi/qrhimetal_p_p.h b/src/gui/rhi/qrhimetal_p_p.h index 2be86db5c8..7876539fcd 100644 --- a/src/gui/rhi/qrhimetal_p_p.h +++ b/src/gui/rhi/qrhimetal_p_p.h @@ -138,6 +138,7 @@ struct QMetalRenderPassDescriptor : public QRhiRenderPassDescriptor QMetalRenderPassDescriptor(QRhiImplementation *rhi); ~QMetalRenderPassDescriptor(); void release() override; + bool isCompatible(const QRhiRenderPassDescriptor *other) const override; // there is no MTLRenderPassDescriptor here as one will be created for each pass in beginPass() diff --git a/src/gui/rhi/qrhinull.cpp b/src/gui/rhi/qrhinull.cpp index fe606f971f..0baea1b9d6 100644 --- a/src/gui/rhi/qrhinull.cpp +++ b/src/gui/rhi/qrhinull.cpp @@ -690,6 +690,12 @@ void QNullRenderPassDescriptor::release() { } +bool QNullRenderPassDescriptor::isCompatible(const QRhiRenderPassDescriptor *other) const +{ + Q_UNUSED(other); + return true; +} + QNullReferenceRenderTarget::QNullReferenceRenderTarget(QRhiImplementation *rhi) : QRhiRenderTarget(rhi), d(rhi) diff --git a/src/gui/rhi/qrhinull_p_p.h b/src/gui/rhi/qrhinull_p_p.h index ce517bfa63..c96f279f7d 100644 --- a/src/gui/rhi/qrhinull_p_p.h +++ b/src/gui/rhi/qrhinull_p_p.h @@ -101,6 +101,7 @@ struct QNullRenderPassDescriptor : public QRhiRenderPassDescriptor QNullRenderPassDescriptor(QRhiImplementation *rhi); ~QNullRenderPassDescriptor(); void release() override; + bool isCompatible(const QRhiRenderPassDescriptor *other) const override; }; struct QNullRenderTargetData diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp index 2d69abb36b..25a85a5a17 100644 --- a/src/gui/rhi/qrhivulkan.cpp +++ b/src/gui/rhi/qrhivulkan.cpp @@ -1032,54 +1032,62 @@ VkFormat QRhiVulkan::optimalDepthStencilFormat() return optimalDsFormat; } -bool QRhiVulkan::createDefaultRenderPass(VkRenderPass *rp, bool hasDepthStencil, VkSampleCountFlagBits samples, VkFormat colorFormat) +bool QRhiVulkan::createDefaultRenderPass(QVkRenderPassDescriptor *rpD, bool hasDepthStencil, VkSampleCountFlagBits samples, VkFormat colorFormat) { - VkAttachmentDescription attDesc[3]; - memset(attDesc, 0, sizeof(attDesc)); - // attachment list layout is color (1), ds (0-1), resolve (0-1) - attDesc[0].format = colorFormat; - attDesc[0].samples = samples; - attDesc[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - attDesc[0].storeOp = samples > VK_SAMPLE_COUNT_1_BIT ? VK_ATTACHMENT_STORE_OP_DONT_CARE : VK_ATTACHMENT_STORE_OP_STORE; - attDesc[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attDesc[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attDesc[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - attDesc[0].finalLayout = samples > VK_SAMPLE_COUNT_1_BIT ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; - - // clear on load + no store + lazy alloc + transient image should play - // nicely with tiled GPUs (no physical backing necessary for ds buffer) - attDesc[1].format = optimalDepthStencilFormat(); - attDesc[1].samples = samples; - attDesc[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - attDesc[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attDesc[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - attDesc[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attDesc[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - attDesc[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + VkAttachmentDescription attDesc; + memset(&attDesc, 0, sizeof(attDesc)); + attDesc.format = colorFormat; + attDesc.samples = samples; + attDesc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + attDesc.storeOp = samples > VK_SAMPLE_COUNT_1_BIT ? VK_ATTACHMENT_STORE_OP_DONT_CARE : VK_ATTACHMENT_STORE_OP_STORE; + attDesc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + attDesc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + attDesc.finalLayout = samples > VK_SAMPLE_COUNT_1_BIT ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + rpD->attDescs.append(attDesc); - if (samples > VK_SAMPLE_COUNT_1_BIT) { - attDesc[2].format = colorFormat; - attDesc[2].samples = VK_SAMPLE_COUNT_1_BIT; - attDesc[2].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - attDesc[2].storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attDesc[2].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attDesc[2].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attDesc[2].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - attDesc[2].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + rpD->colorRefs.append({ 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }); + + if (hasDepthStencil) { + // clear on load + no store + lazy alloc + transient image should play + // nicely with tiled GPUs (no physical backing necessary for ds buffer) + memset(&attDesc, 0, sizeof(attDesc)); + attDesc.format = optimalDepthStencilFormat(); + attDesc.samples = samples; + attDesc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + attDesc.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + attDesc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + attDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + attDesc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + attDesc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + rpD->attDescs.append(attDesc); + + rpD->dsRef = { 1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL }; } - VkAttachmentReference colorRef = { 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; - VkAttachmentReference dsRef = { 1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL }; - VkAttachmentReference resolveRef = { 2, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; + if (samples > VK_SAMPLE_COUNT_1_BIT) { + memset(&attDesc, 0, sizeof(attDesc)); + attDesc.format = colorFormat; + attDesc.samples = VK_SAMPLE_COUNT_1_BIT; + attDesc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + attDesc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + attDesc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + attDesc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + attDesc.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + rpD->attDescs.append(attDesc); + + rpD->resolveRefs.append({ 2, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }); + } VkSubpassDescription subpassDesc; memset(&subpassDesc, 0, sizeof(subpassDesc)); subpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; subpassDesc.colorAttachmentCount = 1; - subpassDesc.pColorAttachments = &colorRef; - subpassDesc.pDepthStencilAttachment = hasDepthStencil ? &dsRef : nullptr; + subpassDesc.pColorAttachments = rpD->colorRefs.constData(); + subpassDesc.pDepthStencilAttachment = hasDepthStencil ? &rpD->dsRef : nullptr; // Replace the first implicit dep (TOP_OF_PIPE / ALL_COMMANDS) with our own. VkSubpassDependency subpassDep; @@ -1095,7 +1103,7 @@ bool QRhiVulkan::createDefaultRenderPass(VkRenderPass *rp, bool hasDepthStencil, memset(&rpInfo, 0, sizeof(rpInfo)); rpInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; rpInfo.attachmentCount = 1; - rpInfo.pAttachments = attDesc; + rpInfo.pAttachments = rpD->attDescs.constData(); rpInfo.subpassCount = 1; rpInfo.pSubpasses = &subpassDesc; rpInfo.dependencyCount = 1; @@ -1106,19 +1114,21 @@ bool QRhiVulkan::createDefaultRenderPass(VkRenderPass *rp, bool hasDepthStencil, if (samples > VK_SAMPLE_COUNT_1_BIT) { rpInfo.attachmentCount += 1; - subpassDesc.pResolveAttachments = &resolveRef; + subpassDesc.pResolveAttachments = rpD->resolveRefs.constData(); } - VkResult err = df->vkCreateRenderPass(dev, &rpInfo, nullptr, rp); + VkResult err = df->vkCreateRenderPass(dev, &rpInfo, nullptr, &rpD->rp); if (err != VK_SUCCESS) { qWarning("Failed to create renderpass: %d", err); return false; } + rpD->hasDepthStencil = hasDepthStencil; + return true; } -bool QRhiVulkan::createOffscreenRenderPass(VkRenderPass *rp, +bool QRhiVulkan::createOffscreenRenderPass(QVkRenderPassDescriptor *rpD, const QRhiColorAttachment *firstColorAttachment, const QRhiColorAttachment *lastColorAttachment, bool preserveColor, @@ -1126,10 +1136,6 @@ bool QRhiVulkan::createOffscreenRenderPass(VkRenderPass *rp, QRhiRenderBuffer *depthStencilBuffer, QRhiTexture *depthTexture) { - QVarLengthArray<VkAttachmentDescription, 8> attDescs; - QVarLengthArray<VkAttachmentReference, 8> colorRefs; - QVarLengthArray<VkAttachmentReference, 8> resolveRefs; - // attachment list layout is color (0-8), ds (0-1), resolve (0-8) for (auto it = firstColorAttachment; it != lastColorAttachment; ++it) { @@ -1150,14 +1156,14 @@ bool QRhiVulkan::createOffscreenRenderPass(VkRenderPass *rp, // this has to interact correctly with activateTextureRenderTarget(), hence leaving in COLOR_ATT attDesc.initialLayout = preserveColor ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED; attDesc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - attDescs.append(attDesc); + rpD->attDescs.append(attDesc); - const VkAttachmentReference ref = { uint32_t(attDescs.count() - 1), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; - colorRefs.append(ref); + const VkAttachmentReference ref = { uint32_t(rpD->attDescs.count() - 1), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; + rpD->colorRefs.append(ref); } - const bool hasDepthStencil = depthStencilBuffer || depthTexture; - if (hasDepthStencil) { + rpD->hasDepthStencil = depthStencilBuffer || depthTexture; + if (rpD->hasDepthStencil) { const VkFormat dsFormat = depthTexture ? QRHI_RES(QVkTexture, depthTexture)->vkformat : QRHI_RES(QVkRenderBuffer, depthStencilBuffer)->vkformat; const VkSampleCountFlagBits samples = depthTexture ? QRHI_RES(QVkTexture, depthTexture)->samples @@ -1174,9 +1180,9 @@ bool QRhiVulkan::createOffscreenRenderPass(VkRenderPass *rp, attDesc.stencilStoreOp = storeOp; attDesc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; attDesc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - attDescs.append(attDesc); + rpD->attDescs.append(attDesc); } - VkAttachmentReference dsRef = { uint32_t(attDescs.count() - 1), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL }; + rpD->dsRef = { uint32_t(rpD->attDescs.count() - 1), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL }; for (auto it = firstColorAttachment; it != lastColorAttachment; ++it) { if (it->resolveTexture()) { @@ -1194,37 +1200,37 @@ bool QRhiVulkan::createOffscreenRenderPass(VkRenderPass *rp, attDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; attDesc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; attDesc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - attDescs.append(attDesc); + rpD->attDescs.append(attDesc); - const VkAttachmentReference ref = { uint32_t(attDescs.count() - 1), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; - resolveRefs.append(ref); + const VkAttachmentReference ref = { uint32_t(rpD->attDescs.count() - 1), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; + rpD->resolveRefs.append(ref); } else { const VkAttachmentReference ref = { VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; - resolveRefs.append(ref); + rpD->resolveRefs.append(ref); } } VkSubpassDescription subpassDesc; memset(&subpassDesc, 0, sizeof(subpassDesc)); subpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpassDesc.colorAttachmentCount = uint32_t(colorRefs.count()); - Q_ASSERT(colorRefs.count() == resolveRefs.count()); - subpassDesc.pColorAttachments = !colorRefs.isEmpty() ? colorRefs.constData() : nullptr; - subpassDesc.pDepthStencilAttachment = hasDepthStencil ? &dsRef : nullptr; - subpassDesc.pResolveAttachments = !resolveRefs.isEmpty() ? resolveRefs.constData() : nullptr; + subpassDesc.colorAttachmentCount = uint32_t(rpD->colorRefs.count()); + Q_ASSERT(rpD->colorRefs.count() == rpD->resolveRefs.count()); + subpassDesc.pColorAttachments = !rpD->colorRefs.isEmpty() ? rpD->colorRefs.constData() : nullptr; + subpassDesc.pDepthStencilAttachment = rpD->hasDepthStencil ? &rpD->dsRef : nullptr; + subpassDesc.pResolveAttachments = !rpD->resolveRefs.isEmpty() ? rpD->resolveRefs.constData() : nullptr; VkRenderPassCreateInfo rpInfo; memset(&rpInfo, 0, sizeof(rpInfo)); rpInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - rpInfo.attachmentCount = uint32_t(attDescs.count()); - rpInfo.pAttachments = attDescs.constData(); + rpInfo.attachmentCount = uint32_t(rpD->attDescs.count()); + rpInfo.pAttachments = rpD->attDescs.constData(); rpInfo.subpassCount = 1; rpInfo.pSubpasses = &subpassDesc; // don't yet know the correct initial/final access and stage stuff for the // implicit deps at this point, so leave it to the resource tracking to // generate barriers - VkResult err = df->vkCreateRenderPass(dev, &rpInfo, nullptr, rp); + VkResult err = df->vkCreateRenderPass(dev, &rpInfo, nullptr, &rpD->rp); if (err != VK_SUCCESS) { qWarning("Failed to create renderpass: %d", err); return false; @@ -4617,12 +4623,8 @@ static inline VkSamplerAddressMode toVkAddressMode(QRhiSampler::AddressMode m) return VK_SAMPLER_ADDRESS_MODE_REPEAT; case QRhiSampler::ClampToEdge: return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - case QRhiSampler::Border: - return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; case QRhiSampler::Mirror: return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT; - case QRhiSampler::MirrorOnce: - return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE; default: Q_UNREACHABLE(); return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; @@ -5505,6 +5507,61 @@ void QVkRenderPassDescriptor::release() rhiD->unregisterResource(this); } +static inline bool attachmentDescriptionEquals(const VkAttachmentDescription &a, const VkAttachmentDescription &b) +{ + return a.format == b.format + && a.samples == b.samples + && a.loadOp == b.loadOp + && a.storeOp == b.storeOp + && a.stencilLoadOp == b.stencilLoadOp + && a.stencilStoreOp == b.stencilStoreOp + && a.initialLayout == b.initialLayout + && a.finalLayout == b.finalLayout; +} + +bool QVkRenderPassDescriptor::isCompatible(const QRhiRenderPassDescriptor *other) const +{ + if (!other) + return false; + + const QVkRenderPassDescriptor *o = QRHI_RES(const QVkRenderPassDescriptor, other); + + if (attDescs.count() != o->attDescs.count()) + return false; + if (colorRefs.count() != o->colorRefs.count()) + return false; + if (resolveRefs.count() != o->resolveRefs.count()) + return false; + if (hasDepthStencil != o->hasDepthStencil) + return false; + + for (int i = 0, ie = colorRefs.count(); i != ie; ++i) { + const uint32_t attIdx = colorRefs[i].attachment; + if (attIdx != o->colorRefs[i].attachment) + return false; + if (attIdx != VK_ATTACHMENT_UNUSED && !attachmentDescriptionEquals(attDescs[attIdx], o->attDescs[attIdx])) + return false; + } + + if (hasDepthStencil) { + const uint32_t attIdx = dsRef.attachment; + if (attIdx != o->dsRef.attachment) + return false; + if (attIdx != VK_ATTACHMENT_UNUSED && !attachmentDescriptionEquals(attDescs[attIdx], o->attDescs[attIdx])) + return false; + } + + for (int i = 0, ie = resolveRefs.count(); i != ie; ++i) { + const uint32_t attIdx = resolveRefs[i].attachment; + if (attIdx != o->resolveRefs[i].attachment) + return false; + if (attIdx != VK_ATTACHMENT_UNUSED && !attachmentDescriptionEquals(attDescs[attIdx], o->attDescs[attIdx])) + return false; + } + + return true; +} + const QRhiNativeHandles *QVkRenderPassDescriptor::nativeHandles() { nativeHandlesStruct.renderPass = rp; @@ -5588,7 +5645,7 @@ QRhiRenderPassDescriptor *QVkTextureRenderTarget::newCompatibleRenderPassDescrip QRHI_RES_RHI(QRhiVulkan); QVkRenderPassDescriptor *rp = new QVkRenderPassDescriptor(m_rhi); - if (!rhiD->createOffscreenRenderPass(&rp->rp, + if (!rhiD->createOffscreenRenderPass(rp, m_desc.cbeginColorAttachments(), m_desc.cendColorAttachments(), m_flags.testFlag(QRhiTextureRenderTarget::PreserveColorContents), @@ -6289,7 +6346,7 @@ QRhiRenderPassDescriptor *QVkSwapChain::newCompatibleRenderPassDescriptor() QRHI_RES_RHI(QRhiVulkan); QVkRenderPassDescriptor *rp = new QVkRenderPassDescriptor(m_rhi); - if (!rhiD->createDefaultRenderPass(&rp->rp, + if (!rhiD->createDefaultRenderPass(rp, m_depthStencil != nullptr, samples, colorFormat)) diff --git a/src/gui/rhi/qrhivulkan_p_p.h b/src/gui/rhi/qrhivulkan_p_p.h index d0e1e6758b..ffa8c59ed5 100644 --- a/src/gui/rhi/qrhivulkan_p_p.h +++ b/src/gui/rhi/qrhivulkan_p_p.h @@ -171,10 +171,16 @@ struct QVkRenderPassDescriptor : public QRhiRenderPassDescriptor QVkRenderPassDescriptor(QRhiImplementation *rhi); ~QVkRenderPassDescriptor(); void release() override; + bool isCompatible(const QRhiRenderPassDescriptor *other) const override; const QRhiNativeHandles *nativeHandles() override; VkRenderPass rp = VK_NULL_HANDLE; bool ownsRp = false; + QVarLengthArray<VkAttachmentDescription, 8> attDescs; + QVarLengthArray<VkAttachmentReference, 8> colorRefs; + QVarLengthArray<VkAttachmentReference, 8> resolveRefs; + bool hasDepthStencil = false; + VkAttachmentReference dsRef; QRhiVulkanRenderPassNativeHandles nativeHandlesStruct; int lastActiveFrameSlot = -1; }; @@ -727,11 +733,11 @@ public: VkFormat optimalDepthStencilFormat(); VkSampleCountFlagBits effectiveSampleCount(int sampleCount); - bool createDefaultRenderPass(VkRenderPass *rp, + bool createDefaultRenderPass(QVkRenderPassDescriptor *rpD, bool hasDepthStencil, VkSampleCountFlagBits samples, VkFormat colorFormat); - bool createOffscreenRenderPass(VkRenderPass *rp, + bool createOffscreenRenderPass(QVkRenderPassDescriptor *rpD, const QRhiColorAttachment *firstColorAttachment, const QRhiColorAttachment *lastColorAttachment, bool preserveColor, diff --git a/src/gui/rhi/rhi.pri b/src/gui/rhi/rhi.pri index 4297a5602b..ccd9592634 100644 --- a/src/gui/rhi/rhi.pri +++ b/src/gui/rhi/rhi.pri @@ -43,15 +43,15 @@ win32 { LIBS += -ld3d11 -ldxgi -ldxguid } -# darwin { -macos { +macos|ios { HEADERS += \ rhi/qrhimetal_p.h \ rhi/qrhimetal_p_p.h SOURCES += \ rhi/qrhimetal.mm - LIBS += -framework AppKit -framework Metal + macos: LIBS += -framework AppKit + LIBS += -framework Metal } include($$PWD/../../3rdparty/VulkanMemoryAllocator.pri) diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index cdec57de71..1b6a802ca2 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -51,6 +51,9 @@ #include <qpa/qplatformintegration.h> #import <QuartzCore/CAEAGLLayer.h> +#ifdef Q_OS_IOS +#import <QuartzCore/CAMetalLayer.h> +#endif #include <QtDebug> @@ -58,9 +61,15 @@ QT_BEGIN_NAMESPACE QIOSWindow::QIOSWindow(QWindow *window) : QPlatformWindow(window) - , m_view([[QUIView alloc] initWithQIOSWindow:this]) , m_windowLevel(0) { +#ifdef Q_OS_IOS + if (window->surfaceType() == QSurface::MetalSurface) + m_view = [[QUIMetalView alloc] initWithQIOSWindow:this]; + else +#endif + m_view = [[QUIView alloc] initWithQIOSWindow:this]; + connect(qGuiApp, &QGuiApplication::applicationStateChanged, this, &QIOSWindow::applicationStateChanged); setParent(QPlatformWindow::parent()); diff --git a/src/plugins/platforms/ios/quiview.h b/src/plugins/platforms/ios/quiview.h index e1d5d5af0c..1ab9481dd6 100644 --- a/src/plugins/platforms/ios/quiview.h +++ b/src/plugins/platforms/ios/quiview.h @@ -70,3 +70,7 @@ QT_END_NAMESPACE @property (nonatomic, readonly) UIEdgeInsets qt_safeAreaInsets; @end +#ifdef Q_OS_IOS +@interface QUIMetalView : QUIView +@end +#endif diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm index 91a186bace..59eae07388 100644 --- a/src/plugins/platforms/ios/quiview.mm +++ b/src/plugins/platforms/ios/quiview.mm @@ -100,13 +100,15 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") - (instancetype)initWithFrame:(CGRect)frame { if ((self = [super initWithFrame:frame])) { - // Set up EAGL layer - CAEAGLLayer *eaglLayer = static_cast<CAEAGLLayer *>(self.layer); - eaglLayer.opaque = TRUE; - eaglLayer.drawableProperties = @{ - kEAGLDrawablePropertyRetainedBacking: @(YES), - kEAGLDrawablePropertyColorFormat: kEAGLColorFormatRGBA8 - }; + if ([self.layer isKindOfClass:[CAEAGLLayer class]]) { + // Set up EAGL layer + CAEAGLLayer *eaglLayer = static_cast<CAEAGLLayer *>(self.layer); + eaglLayer.opaque = TRUE; + eaglLayer.drawableProperties = @{ + kEAGLDrawablePropertyRetainedBacking: @(YES), + kEAGLDrawablePropertyColorFormat: kEAGLColorFormatRGBA8 + }; + } if (isQtApplication()) self.hidden = YES; @@ -675,6 +677,25 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") @end +#ifdef Q_OS_IOS +@implementation QUIMetalView + ++ (Class)layerClass +{ +#ifdef TARGET_IPHONE_SIMULATOR + if (@available(ios 13.0, *)) +#endif + + return [CAMetalLayer class]; + +#ifdef TARGET_IPHONE_SIMULATOR + return nil; +#endif +} + +@end +#endif + #ifndef QT_NO_ACCESSIBILITY // Include category as an alternative to using -ObjC (Apple QA1490) #include "quiview_accessibility.mm" diff --git a/src/plugins/styles/windowsvista/windowsvista.pro b/src/plugins/styles/windowsvista/windowsvista.pro index c08db7f533..483914c13d 100644 --- a/src/plugins/styles/windowsvista/windowsvista.pro +++ b/src/plugins/styles/windowsvista/windowsvista.pro @@ -11,9 +11,7 @@ HEADERS += qwindowsxpstyle_p.h qwindowsxpstyle_p_p.h SOURCES += qwindowsxpstyle.cpp QMAKE_USE_PRIVATE += user32 gdi32 - -# DEFINES/LIBS needed for qwizard_win.cpp and the styles -include(../../../widgets/kernel/win.pri) +LIBS_PRIVATE *= -luxtheme DISTFILES += windowsvistastyle.json diff --git a/src/tools/androidtestrunner/main.cpp b/src/tools/androidtestrunner/main.cpp index 1046c7b7ef..5471db3afd 100644 --- a/src/tools/androidtestrunner/main.cpp +++ b/src/tools/androidtestrunner/main.cpp @@ -460,7 +460,7 @@ int main(int argc, char *argv[]) } // Run androiddeployqt - static auto verbose = g_options.verbose ? QStringLiteral("--verbose") : QStringLiteral(); + static auto verbose = g_options.verbose ? QStringLiteral("--verbose") : QString(); if (!execCommand(QStringLiteral("%1 %3 --reinstall --output %2 --apk %4").arg(g_options.androidDeployQtCommand, g_options.buildPath, verbose, diff --git a/src/widgets/kernel/qlayoutengine.cpp b/src/widgets/kernel/qlayoutengine.cpp index 19a47075a6..92b362e89d 100644 --- a/src/widgets/kernel/qlayoutengine.cpp +++ b/src/widgets/kernel/qlayoutengine.cpp @@ -376,7 +376,11 @@ Q_WIDGETS_EXPORT QSize qSmartMinSize(const QSize &sizeHint, const QSize &minSize Q_WIDGETS_EXPORT QSize qSmartMinSize(const QWidgetItem *i) { +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QWidget *w = const_cast<QWidgetItem *>(i)->widget(); +#else + QWidget *w = i->widget(); +#endif return qSmartMinSize(w->sizeHint(), w->minimumSizeHint(), w->minimumSize(), w->maximumSize(), w->sizePolicy()); @@ -414,8 +418,11 @@ Q_WIDGETS_EXPORT QSize qSmartMaxSize(const QSize &sizeHint, Q_WIDGETS_EXPORT QSize qSmartMaxSize(const QWidgetItem *i, Qt::Alignment align) { - QWidget *w = const_cast<QWidgetItem*>(i)->widget(); - +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + QWidget *w = const_cast<QWidgetItem *>(i)->widget(); +#else + QWidget *w = i->widget(); +#endif return qSmartMaxSize(w->sizeHint().expandedTo(w->minimumSizeHint()), w->minimumSize(), w->maximumSize(), w->sizePolicy(), align); } diff --git a/src/widgets/kernel/qlayoutitem.cpp b/src/widgets/kernel/qlayoutitem.cpp index ca5a89e4dc..fc02afb014 100644 --- a/src/widgets/kernel/qlayoutitem.cpp +++ b/src/widgets/kernel/qlayoutitem.cpp @@ -291,14 +291,12 @@ void QSpacerItem::changeSize(int w, int h, QSizePolicy::Policy hPolicy, /*! Destructor. */ -QWidgetItem::~QWidgetItem() {} +QWidgetItem::~QWidgetItem() = default; /*! Destroys the QLayoutItem. */ -QLayoutItem::~QLayoutItem() -{ -} +QLayoutItem::~QLayoutItem() = default; /*! Invalidates any cached information in this layout item. @@ -362,7 +360,11 @@ QSpacerItem * QSpacerItem::spacerItem() \sa layout(), spacerItem() */ +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QWidget *QLayoutItem::widget() +#else +QWidget *QLayoutItem::widget() const +#endif { return nullptr; } @@ -370,7 +372,11 @@ QWidget *QLayoutItem::widget() /*! Returns the widget managed by this item. */ +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QWidget *QWidgetItem::widget() +#else +QWidget *QWidgetItem::widget() const +#endif { return wid; } diff --git a/src/widgets/kernel/qlayoutitem.h b/src/widgets/kernel/qlayoutitem.h index 059ff2d470..8553e20adc 100644 --- a/src/widgets/kernel/qlayoutitem.h +++ b/src/widgets/kernel/qlayoutitem.h @@ -74,7 +74,11 @@ public: virtual int minimumHeightForWidth(int) const; virtual void invalidate(); +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) virtual QWidget *widget(); +#else + virtual QWidget *widget() const; +#endif virtual QLayout *layout(); virtual QSpacerItem *spacerItem(); @@ -133,7 +137,11 @@ public: bool isEmpty() const override; void setGeometry(const QRect&) override; QRect geometry() const override; +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QWidget *widget() override; +#else + QWidget *widget() const override; +#endif bool hasHeightForWidth() const override; int heightForWidth(int) const override; diff --git a/src/widgets/kernel/win.pri b/src/widgets/kernel/win.pri index 3b3170beb1..eede987b4c 100644 --- a/src/widgets/kernel/win.pri +++ b/src/widgets/kernel/win.pri @@ -1,7 +1,6 @@ # Qt/Windows only configuration file # -------------------------------------------------------------------- -INCLUDEPATH += ../3rdparty/wintab !winrt { LIBS_PRIVATE *= -luxtheme -ldwmapi QMAKE_USE_PRIVATE += shell32 diff --git a/src/widgets/widgets/qdockwidget_p.h b/src/widgets/widgets/qdockwidget_p.h index bc6ac86c45..e663ec4c2d 100644 --- a/src/widgets/widgets/qdockwidget_p.h +++ b/src/widgets/widgets/qdockwidget_p.h @@ -201,7 +201,11 @@ inline QLayoutItem *QDockWidgetItem::dockWidgetChildItem() const inline QDockWidgetLayout *QDockWidgetItem::dockWidgetLayout() const { +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QWidget *w = const_cast<QDockWidgetItem*>(this)->widget(); +#else + QWidget *w = widget(); +#endif if (w != nullptr) return qobject_cast<QDockWidgetLayout*>(w->layout()); return nullptr; diff --git a/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp b/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp index 533d6b17b1..302630ae15 100644 --- a/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp +++ b/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp @@ -52,7 +52,7 @@ # define TST_D3D11 #endif -#ifdef Q_OS_DARWIN +#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) # include <QtGui/private/qrhimetal_p.h> # define TST_MTL #endif @@ -91,6 +91,10 @@ private slots: void renderToTextureTexturedQuadAndUniformBuffer(); void renderToWindowSimple_data(); void renderToWindowSimple(); + void srbLayoutCompatibility_data(); + void srbLayoutCompatibility(); + void renderPassDescriptorCompatibility_data(); + void renderPassDescriptorCompatibility(); private: struct { @@ -1728,5 +1732,318 @@ void tst_QRhi::renderToWindowSimple() QVERIFY(redCount < blueCount); } +void tst_QRhi::srbLayoutCompatibility_data() +{ + rhiTestData(); +} + +void tst_QRhi::srbLayoutCompatibility() +{ + QFETCH(QRhi::Implementation, impl); + QFETCH(QRhiInitParams *, initParams); + + QScopedPointer<QRhi> rhi(QRhi::create(impl, initParams, QRhi::Flags(), nullptr)); + if (!rhi) + QSKIP("QRhi could not be created, skipping testing texture resource updates"); + + QScopedPointer<QRhiTexture> texture(rhi->newTexture(QRhiTexture::RGBA8, QSize(512, 512))); + QVERIFY(texture->build()); + QScopedPointer<QRhiSampler> sampler(rhi->newSampler(QRhiSampler::Nearest, QRhiSampler::Nearest, QRhiSampler::None, + QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge)); + QVERIFY(sampler->build()); + QScopedPointer<QRhiSampler> otherSampler(rhi->newSampler(QRhiSampler::Nearest, QRhiSampler::Nearest, QRhiSampler::None, + QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge)); + QVERIFY(otherSampler->build()); + QScopedPointer<QRhiBuffer> buf(rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 1024)); + QVERIFY(buf->build()); + QScopedPointer<QRhiBuffer> otherBuf(rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 256)); + QVERIFY(otherBuf->build()); + + // empty (compatible) + { + QScopedPointer<QRhiShaderResourceBindings> srb1(rhi->newShaderResourceBindings()); + QVERIFY(srb1->build()); + + QScopedPointer<QRhiShaderResourceBindings> srb2(rhi->newShaderResourceBindings()); + QVERIFY(srb2->build()); + + QVERIFY(srb1->isLayoutCompatible(srb2.data())); + QVERIFY(srb2->isLayoutCompatible(srb1.data())); + } + + // different count (not compatible) + { + QScopedPointer<QRhiShaderResourceBindings> srb1(rhi->newShaderResourceBindings()); + QVERIFY(srb1->build()); + + QScopedPointer<QRhiShaderResourceBindings> srb2(rhi->newShaderResourceBindings()); + srb2->setBindings({ + QRhiShaderResourceBinding::sampledTexture(0, QRhiShaderResourceBinding::FragmentStage, texture.data(), sampler.data()) + }); + QVERIFY(srb2->build()); + + QVERIFY(!srb1->isLayoutCompatible(srb2.data())); + QVERIFY(!srb2->isLayoutCompatible(srb1.data())); + } + + // full match (compatible) + { + QScopedPointer<QRhiShaderResourceBindings> srb1(rhi->newShaderResourceBindings()); + srb1->setBindings({ + QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage, buf.data()), + QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, texture.data(), sampler.data()) + }); + QVERIFY(srb1->build()); + + QScopedPointer<QRhiShaderResourceBindings> srb2(rhi->newShaderResourceBindings()); + srb2->setBindings({ + QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage, buf.data()), + QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, texture.data(), sampler.data()) + }); + QVERIFY(srb2->build()); + + QVERIFY(srb1->isLayoutCompatible(srb2.data())); + QVERIFY(srb2->isLayoutCompatible(srb1.data())); + } + + // different visibility (not compatible) + { + QScopedPointer<QRhiShaderResourceBindings> srb1(rhi->newShaderResourceBindings()); + srb1->setBindings({ + QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage, buf.data()), + }); + QVERIFY(srb1->build()); + + QScopedPointer<QRhiShaderResourceBindings> srb2(rhi->newShaderResourceBindings()); + srb2->setBindings({ + QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage, buf.data()), + }); + QVERIFY(srb2->build()); + + QVERIFY(!srb1->isLayoutCompatible(srb2.data())); + QVERIFY(!srb2->isLayoutCompatible(srb1.data())); + } + + // different binding points (not compatible) + { + QScopedPointer<QRhiShaderResourceBindings> srb1(rhi->newShaderResourceBindings()); + srb1->setBindings({ + QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage, buf.data()), + }); + QVERIFY(srb1->build()); + + QScopedPointer<QRhiShaderResourceBindings> srb2(rhi->newShaderResourceBindings()); + srb2->setBindings({ + QRhiShaderResourceBinding::uniformBuffer(1, QRhiShaderResourceBinding::VertexStage, buf.data()), + }); + QVERIFY(srb2->build()); + + QVERIFY(!srb1->isLayoutCompatible(srb2.data())); + QVERIFY(!srb2->isLayoutCompatible(srb1.data())); + } + + // different buffer region offset and size (compatible) + { + QScopedPointer<QRhiShaderResourceBindings> srb1(rhi->newShaderResourceBindings()); + srb1->setBindings({ + QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage, buf.data(), rhi->ubufAligned(1), 128), + QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, texture.data(), sampler.data()) + }); + QVERIFY(srb1->build()); + + QScopedPointer<QRhiShaderResourceBindings> srb2(rhi->newShaderResourceBindings()); + srb2->setBindings({ + QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage, buf.data()), + QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, texture.data(), sampler.data()) + }); + QVERIFY(srb2->build()); + + QVERIFY(srb1->isLayoutCompatible(srb2.data())); + QVERIFY(srb2->isLayoutCompatible(srb1.data())); + } + + // different resources (compatible) + { + QScopedPointer<QRhiShaderResourceBindings> srb1(rhi->newShaderResourceBindings()); + srb1->setBindings({ + QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage, otherBuf.data()), + QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, texture.data(), otherSampler.data()) + }); + QVERIFY(srb1->build()); + + QScopedPointer<QRhiShaderResourceBindings> srb2(rhi->newShaderResourceBindings()); + srb2->setBindings({ + QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage, buf.data()), + QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, texture.data(), sampler.data()) + }); + QVERIFY(srb2->build()); + + QVERIFY(srb1->isLayoutCompatible(srb2.data())); + QVERIFY(srb2->isLayoutCompatible(srb1.data())); + } +} + +void tst_QRhi::renderPassDescriptorCompatibility_data() +{ + rhiTestData(); +} + +void tst_QRhi::renderPassDescriptorCompatibility() +{ + QFETCH(QRhi::Implementation, impl); + QFETCH(QRhiInitParams *, initParams); + + QScopedPointer<QRhi> rhi(QRhi::create(impl, initParams, QRhi::Flags(), nullptr)); + if (!rhi) + QSKIP("QRhi could not be created, skipping testing texture resource updates"); + + // Note that checking compatibility is only relevant with backends where + // there is a concept of renderpass descriptions (Vulkan, and partially + // Metal). It is perfectly fine for isCompatible() to always return true + // when that is not the case (D3D11, OpenGL). Hence the 'if (Vulkan or + // Metal)' for all the negative tests. Also note "partial" for Metal: + // resolve textures for examples have no effect on compatibility with Metal. + + // tex and tex2 have the same format + QScopedPointer<QRhiTexture> tex(rhi->newTexture(QRhiTexture::RGBA8, QSize(512, 512), 1, QRhiTexture::RenderTarget)); + QVERIFY(tex->build()); + QScopedPointer<QRhiTexture> tex2(rhi->newTexture(QRhiTexture::RGBA8, QSize(512, 512), 1, QRhiTexture::RenderTarget)); + QVERIFY(tex2->build()); + + QScopedPointer<QRhiRenderBuffer> ds(rhi->newRenderBuffer(QRhiRenderBuffer::DepthStencil, QSize(512, 512))); + QVERIFY(ds->build()); + + // two texture rendertargets with tex and tex2 as color0 (compatible) + { + QScopedPointer<QRhiTextureRenderTarget> rt(rhi->newTextureRenderTarget({ tex.data() })); + QScopedPointer<QRhiRenderPassDescriptor> rpDesc(rt->newCompatibleRenderPassDescriptor()); + rt->setRenderPassDescriptor(rpDesc.data()); + QVERIFY(rt->build()); + + QScopedPointer<QRhiTextureRenderTarget> rt2(rhi->newTextureRenderTarget({ tex2.data() })); + QScopedPointer<QRhiRenderPassDescriptor> rpDesc2(rt2->newCompatibleRenderPassDescriptor()); + rt2->setRenderPassDescriptor(rpDesc2.data()); + QVERIFY(rt2->build()); + + QVERIFY(rpDesc->isCompatible(rpDesc2.data())); + QVERIFY(rpDesc2->isCompatible(rpDesc.data())); + } + + // two texture rendertargets with tex and tex2 as color0, and a depth-stencil attachment as well (compatible) + { + QRhiTextureRenderTargetDescription desc({ tex.data() }, ds.data()); + QScopedPointer<QRhiTextureRenderTarget> rt(rhi->newTextureRenderTarget(desc)); + QScopedPointer<QRhiRenderPassDescriptor> rpDesc(rt->newCompatibleRenderPassDescriptor()); + rt->setRenderPassDescriptor(rpDesc.data()); + QVERIFY(rt->build()); + + QScopedPointer<QRhiTextureRenderTarget> rt2(rhi->newTextureRenderTarget(desc)); + QScopedPointer<QRhiRenderPassDescriptor> rpDesc2(rt2->newCompatibleRenderPassDescriptor()); + rt2->setRenderPassDescriptor(rpDesc2.data()); + QVERIFY(rt2->build()); + + QVERIFY(rpDesc->isCompatible(rpDesc2.data())); + QVERIFY(rpDesc2->isCompatible(rpDesc.data())); + } + + // now one of them does not have the ds attachment (not compatible) + { + QScopedPointer<QRhiTextureRenderTarget> rt(rhi->newTextureRenderTarget({ { tex.data() }, ds.data() })); + QScopedPointer<QRhiRenderPassDescriptor> rpDesc(rt->newCompatibleRenderPassDescriptor()); + rt->setRenderPassDescriptor(rpDesc.data()); + QVERIFY(rt->build()); + + QScopedPointer<QRhiTextureRenderTarget> rt2(rhi->newTextureRenderTarget({ tex.data() })); + QScopedPointer<QRhiRenderPassDescriptor> rpDesc2(rt2->newCompatibleRenderPassDescriptor()); + rt2->setRenderPassDescriptor(rpDesc2.data()); + QVERIFY(rt2->build()); + + if (impl == QRhi::Vulkan || impl == QRhi::Metal) { + QVERIFY(!rpDesc->isCompatible(rpDesc2.data())); + QVERIFY(!rpDesc2->isCompatible(rpDesc.data())); + } + } + + if (rhi->isFeatureSupported(QRhi::MultisampleRenderBuffer)) { + // resolve attachments (compatible) + { + QScopedPointer<QRhiRenderBuffer> msaaRenderBuffer(rhi->newRenderBuffer(QRhiRenderBuffer::Color, QSize(512, 512), 4)); + QVERIFY(msaaRenderBuffer->build()); + QScopedPointer<QRhiRenderBuffer> msaaRenderBuffer2(rhi->newRenderBuffer(QRhiRenderBuffer::Color, QSize(512, 512), 4)); + QVERIFY(msaaRenderBuffer2->build()); + + QRhiColorAttachment colorAtt(msaaRenderBuffer.data()); // color0, multisample + colorAtt.setResolveTexture(tex.data()); // resolved into a non-msaa texture + QScopedPointer<QRhiTextureRenderTarget> rt(rhi->newTextureRenderTarget({ colorAtt })); + QScopedPointer<QRhiRenderPassDescriptor> rpDesc(rt->newCompatibleRenderPassDescriptor()); + rt->setRenderPassDescriptor(rpDesc.data()); + QVERIFY(rt->build()); + + QRhiColorAttachment colorAtt2(msaaRenderBuffer2.data()); // color0, multisample + colorAtt2.setResolveTexture(tex2.data()); // resolved into a non-msaa texture + QScopedPointer<QRhiTextureRenderTarget> rt2(rhi->newTextureRenderTarget({ colorAtt2 })); + QScopedPointer<QRhiRenderPassDescriptor> rpDesc2(rt2->newCompatibleRenderPassDescriptor()); + rt2->setRenderPassDescriptor(rpDesc2.data()); + QVERIFY(rt2->build()); + + QVERIFY(rpDesc->isCompatible(rpDesc2.data())); + QVERIFY(rpDesc2->isCompatible(rpDesc.data())); + } + + // missing resolve for one of them (not compatible) + { + QScopedPointer<QRhiRenderBuffer> msaaRenderBuffer(rhi->newRenderBuffer(QRhiRenderBuffer::Color, QSize(512, 512), 4)); + QVERIFY(msaaRenderBuffer->build()); + QScopedPointer<QRhiRenderBuffer> msaaRenderBuffer2(rhi->newRenderBuffer(QRhiRenderBuffer::Color, QSize(512, 512), 4)); + QVERIFY(msaaRenderBuffer2->build()); + + QRhiColorAttachment colorAtt(msaaRenderBuffer.data()); // color0, multisample + colorAtt.setResolveTexture(tex.data()); // resolved into a non-msaa texture + QScopedPointer<QRhiTextureRenderTarget> rt(rhi->newTextureRenderTarget({ colorAtt })); + QScopedPointer<QRhiRenderPassDescriptor> rpDesc(rt->newCompatibleRenderPassDescriptor()); + rt->setRenderPassDescriptor(rpDesc.data()); + QVERIFY(rt->build()); + + QRhiColorAttachment colorAtt2(msaaRenderBuffer2.data()); // color0, multisample + QScopedPointer<QRhiTextureRenderTarget> rt2(rhi->newTextureRenderTarget({ colorAtt2 })); + QScopedPointer<QRhiRenderPassDescriptor> rpDesc2(rt2->newCompatibleRenderPassDescriptor()); + rt2->setRenderPassDescriptor(rpDesc2.data()); + QVERIFY(rt2->build()); + + if (impl == QRhi::Vulkan) { // no Metal here + QVERIFY(!rpDesc->isCompatible(rpDesc2.data())); + QVERIFY(!rpDesc2->isCompatible(rpDesc.data())); + } + } + } else { + qDebug("Skipping multisample renderbuffer dependent tests"); + } + + if (rhi->isTextureFormatSupported(QRhiTexture::RGBA32F)) { + QScopedPointer<QRhiTexture> tex3(rhi->newTexture(QRhiTexture::RGBA32F, QSize(512, 512), 1, QRhiTexture::RenderTarget)); + QVERIFY(tex3->build()); + + // different texture formats (not compatible) + { + QScopedPointer<QRhiTextureRenderTarget> rt(rhi->newTextureRenderTarget({ tex.data() })); + QScopedPointer<QRhiRenderPassDescriptor> rpDesc(rt->newCompatibleRenderPassDescriptor()); + rt->setRenderPassDescriptor(rpDesc.data()); + QVERIFY(rt->build()); + + QScopedPointer<QRhiTextureRenderTarget> rt2(rhi->newTextureRenderTarget({ tex3.data() })); + QScopedPointer<QRhiRenderPassDescriptor> rpDesc2(rt2->newCompatibleRenderPassDescriptor()); + rt2->setRenderPassDescriptor(rpDesc2.data()); + QVERIFY(rt2->build()); + + if (impl == QRhi::Vulkan || impl == QRhi::Metal) { + QVERIFY(!rpDesc->isCompatible(rpDesc2.data())); + QVERIFY(!rpDesc2->isCompatible(rpDesc.data())); + } + } + } else { + qDebug("Skipping texture format dependent tests"); + } +} + #include <tst_qrhi.moc> QTEST_MAIN(tst_QRhi) diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp index 953791818e..0010718d3e 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp @@ -8299,20 +8299,14 @@ void tst_QGraphicsItem::sorting() _paintedItems.clear(); - view.viewport()->repaint(); -#if defined(Q_OS_MAC) - // There's no difference between repaint and update on the Mac, - // so we have to process events here to make sure we get the event. - QTest::qWait(100); -#endif - + view.viewport()->update(); const GraphicsItems expected{grid[0][0], grid[0][1], grid[0][2], grid[0][3], grid[1][0], grid[1][1], grid[1][2], grid[1][3], grid[2][0], grid[2][1], grid[2][2], grid[2][3], grid[3][0], grid[3][1], grid[3][2], grid[3][3], grid[4][0], grid[4][1], grid[4][2], grid[4][3], item1, item2}; - QCOMPARE(_paintedItems, expected); + QTRY_COMPARE(_paintedItems, expected); } void tst_QGraphicsItem::itemHasNoContents() @@ -8339,13 +8333,7 @@ void tst_QGraphicsItem::itemHasNoContents() _paintedItems.clear(); - view.viewport()->repaint(); -#ifdef Q_OS_MAC - // There's no difference between update() and repaint() on the Mac, - // so we have to process events here to make sure we get the event. - QTest::qWait(10); -#endif - + view.viewport()->update(); QTRY_COMPARE(_paintedItems, GraphicsItems{item2}); } diff --git a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp index 4a33665cb9..ea89e2422b 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp @@ -358,13 +358,13 @@ void tst_QGraphicsView::renderHints() QCOMPARE(item->hints, 0); view.show(); QVERIFY(QTest::qWaitForWindowExposed(&view)); - view.repaint(); + view.update(); QTRY_COMPARE(item->hints, view.renderHints()); view.setRenderHints(QPainter::Antialiasing); QCOMPARE(view.renderHints(), QPainter::Antialiasing); - view.repaint(); + view.update(); QTRY_COMPARE(item->hints, view.renderHints()); } @@ -2631,13 +2631,12 @@ void tst_QGraphicsView::optimizationFlags() class MessUpPainterItem : public QGraphicsRectItem { public: - MessUpPainterItem(const QRectF &rect) : QGraphicsRectItem(rect), dirtyPainter(false) - { } - - bool dirtyPainter; - + using QGraphicsRectItem::QGraphicsRectItem; + bool dirtyPainter = false; + bool receivedPaintEvent = false; void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *w) { + receivedPaintEvent = true; dirtyPainter = (painter->pen().color() != w->palette().color(w->foregroundRole())); painter->setPen(Qt::red); } @@ -2675,18 +2674,22 @@ void tst_QGraphicsView::optimizationFlags_dontSavePainterState() QGraphicsView view(&scene); view.show(); QVERIFY(QTest::qWaitForWindowExposed(&view)); - view.viewport()->repaint(); + parent->receivedPaintEvent = false; + child->receivedPaintEvent = false; + view.viewport()->update(); + QTRY_VERIFY(parent->receivedPaintEvent); + QTRY_VERIFY(child->receivedPaintEvent); QVERIFY(!parent->dirtyPainter); QVERIFY(!child->dirtyPainter); view.setOptimizationFlags(QGraphicsView::DontSavePainterState); - view.viewport()->repaint(); + parent->receivedPaintEvent = false; + child->receivedPaintEvent = false; + view.viewport()->update(); -#ifdef Q_OS_MAC - // Repaint on OS X actually does require spinning the event loop. - QTest::qWait(100); -#endif + QTRY_VERIFY(parent->receivedPaintEvent); + QTRY_VERIFY(child->receivedPaintEvent); QVERIFY(!parent->dirtyPainter); QVERIFY(child->dirtyPainter); @@ -2753,7 +2756,7 @@ void tst_QGraphicsView::optimizationFlags_dontSavePainterState2() QVERIFY(QTest::qWaitForWindowExposed(&view)); // Make sure the view is repainted; otherwise the tests below will fail. - view.viewport()->repaint(); + view.viewport()->update(); QTRY_VERIFY(view.painted); // Make sure the painter's world transform is preserved after drawItems. @@ -4732,14 +4735,12 @@ void tst_QGraphicsView::QTBUG_5859_exposedRect() QGraphicsView view(&scene); view.scale(4.15, 4.15); view.showNormal(); - qApp->setActiveWindow(&view); + QApplication::setActiveWindow(&view); QVERIFY(QTest::qWaitForWindowExposed(&view)); QVERIFY(QTest::qWaitForWindowActive(&view)); - view.viewport()->repaint(10,10,20,20); - QApplication::processEvents(); - - QCOMPARE(item.lastExposedRect, scene.lastBackgroundExposedRect); + view.viewport()->update(10,10,20,20); + QTRY_COMPARE(item.lastExposedRect, scene.lastBackgroundExposedRect); } #ifndef QT_NO_CURSOR diff --git a/tests/auto/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/auto/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp index c42e74ddbd..e42640c066 100644 --- a/tests/auto/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp @@ -1186,7 +1186,7 @@ void tst_QGraphicsWidget::layoutDirection() for (int i = 0; i < children.count(); ++i) { QTRY_COMPARE(children[i]->layoutDirection(), layoutDirection); QTRY_COMPARE(children[i]->testAttribute(Qt::WA_SetLayoutDirection), false); - view->repaint(); + view->update(); QTRY_COMPARE(children[i]->m_painterLayoutDirection, layoutDirection); } } diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp index d332c7e291..23e2ec8516 100644 --- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp @@ -77,6 +77,30 @@ static void initStandardTreeModel(QStandardItemModel *model) model->insertRow(2, item); } +class TreeView : public QTreeView +{ + Q_OBJECT +public: + using QTreeView::QTreeView; + using QTreeView::selectedIndexes; + + void paintEvent(QPaintEvent *event) override + { + QTreeView::paintEvent(event); + wasPainted = true; + } + bool wasPainted = false; +public slots: + void handleSelectionChanged() + { + //let's select the last item + QModelIndex idx = model()->index(0, 0); + selectionModel()->select(QItemSelection(idx, idx), QItemSelectionModel::Select); + disconnect(selectionModel(), &QItemSelectionModel::selectionChanged, + this, &TreeView::handleSelectionChanged); + } +}; + class tst_QTreeView : public QObject { Q_OBJECT @@ -2980,7 +3004,7 @@ void tst_QTreeView::evilModel() { QFETCH(bool, visible); // init - QTreeView view; + TreeView view; EvilModel model; view.setModel(&model); view.setVisible(visible); @@ -3018,7 +3042,7 @@ void tst_QTreeView::evilModel() view.scrollTo(thirdLevel); model.change(); - view.repaint(); + view.update(); // will not do anything since view is not visible model.change(); QTest::mouseDClick(view.viewport(), Qt::LeftButton); @@ -3175,7 +3199,7 @@ void tst_QTreeView::filterProxyModelCrash() QSortFilterProxyModel proxy; proxy.setSourceModel(&model); - QTreeView view; + TreeView view; view.setModel(&proxy); view.show(); QVERIFY(QTest::qWaitForWindowExposed(&view)); @@ -3184,7 +3208,8 @@ void tst_QTreeView::filterProxyModelCrash() QTest::qWait(20); proxy.invalidate(); - view.repaint(); //used to crash + view.update(); //used to crash + QTRY_VERIFY(view.wasPainted); } void tst_QTreeView::renderToPixmap_data() @@ -3652,10 +3677,7 @@ void tst_QTreeView::task220298_selectColumns() } }; - class TreeView : public QTreeView { - public: - using QTreeView::selectedIndexes; - } view; + TreeView view; Model model; view.setModel(&model); view.show(); @@ -4004,20 +4026,6 @@ void tst_QTreeView::task254234_proxySort() QCOMPARE(view.model()->data(view.model()->index(1, 1)).toString(), QString::fromLatin1("g")); } -class TreeView : public QTreeView -{ - Q_OBJECT -public slots: - void handleSelectionChanged() - { - //let's select the last item - QModelIndex idx = model()->index(0, 0); - selectionModel()->select(QItemSelection(idx, idx), QItemSelectionModel::Select); - disconnect(selectionModel(), &QItemSelectionModel::selectionChanged, - this, &TreeView::handleSelectionChanged); - } -}; - void tst_QTreeView::task248022_changeSelection() { //we check that changing the selection between the mouse press and the mouse release diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 3f2b8bca13..07f84595fd 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -8385,12 +8385,9 @@ void tst_QWidget::resizeInPaintEvent() widget.resizeInPaintEvent = true; // This will call resize in the paintEvent, which in turn will call // invalidateBackingStore() and a new update request should be posted. - widget.repaint(); - QCOMPARE(widget.numPaintEvents, 1); - widget.numPaintEvents = 0; - - // Make sure the resize triggers another update. - QTRY_COMPARE(widget.numPaintEvents, 1); + // the resize triggers another update. + widget.update(); + QTRY_COMPARE(widget.numPaintEvents, 2); } void tst_QWidget::opaqueChildren() @@ -8559,8 +8556,8 @@ void tst_QWidget::immediateRepaintAfterInvalidateBackingStore() // The entire widget is already dirty, but this time we want to update immediately // by calling repaint(), and thus we have to repaint the widget and not wait for // the UpdateRequest to be sent when we get back to the event loop. - widget->repaint(); - QCOMPARE(widget->numPaintEvents, 1); + widget->update(); + QTRY_COMPARE(widget->numPaintEvents, 1); } #endif @@ -9832,7 +9829,7 @@ public: if (!static_cast<QWidgetPrivate*>(d_ptr.data())->maybeRepaintManager()) { static_cast<QWidgetPrivate*>(d_ptr.data())->topData()->repaintManager.reset(new QWidgetRepaintManager(this)); static_cast<QWidgetPrivate*>(d_ptr.data())->invalidateBackingStore(this->rect()); - repaint(); + update(); } } }; @@ -9855,7 +9852,7 @@ void tst_QWidget::scrollWithoutBackingStore() scrollable.scroll(-25,-25); QCOMPARE(child.pos(),QPoint(25,25)); scrollable.enableBackingStore(); - QCOMPARE(child.pos(),QPoint(25,25)); + QTRY_COMPARE(child.pos(),QPoint(25,25)); } #endif diff --git a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp index bbf7e27a7a..c2475be8b4 100644 --- a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp +++ b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp @@ -79,24 +79,22 @@ using namespace QTestPrivate; class StyleOptionTestStyle : public QCommonStyle { -private: - bool readOnly; - public: - inline StyleOptionTestStyle() : QCommonStyle(), readOnly(false) - { - } + bool readOnly = false; + mutable bool wasDrawn = false; - inline void setReadOnly(bool readOnly) + using QCommonStyle::QCommonStyle; + void setReadOnly(bool readOnly) { this->readOnly = readOnly; } - inline void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *, - const QWidget *) const + void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *, + const QWidget *) const override { switch (pe) { case PE_PanelLineEdit: + wasDrawn = true; if (readOnly) QVERIFY(opt->state & QStyle::State_ReadOnly); else @@ -3287,19 +3285,22 @@ void tst_QLineEdit::readOnlyStyleOption() QLineEdit *testWidget = ensureTestWidget(); bool wasReadOnly = testWidget->isReadOnly(); QStyle *oldStyle = testWidget->style(); + testWidget->show(); + QTRY_VERIFY(QTest::qWaitForWindowExposed(testWidget)); StyleOptionTestStyle myStyle; testWidget->setStyle(&myStyle); myStyle.setReadOnly(true); testWidget->setReadOnly(true); - testWidget->repaint(); - qApp->processEvents(); + testWidget->update(); + QTRY_VERIFY(myStyle.wasDrawn); + myStyle.wasDrawn = false; testWidget->setReadOnly(false); myStyle.setReadOnly(false); - testWidget->repaint(); - qApp->processEvents(); + testWidget->update(); + QTRY_VERIFY(myStyle.wasDrawn); testWidget->setReadOnly(wasReadOnly); testWidget->setStyle(oldStyle); diff --git a/tests/manual/rhi/hellominimalcrossgfxtriangle/hellominimalcrossgfxtriangle.cpp b/tests/manual/rhi/hellominimalcrossgfxtriangle/hellominimalcrossgfxtriangle.cpp index ea1fefc308..9b03a48bfe 100644 --- a/tests/manual/rhi/hellominimalcrossgfxtriangle/hellominimalcrossgfxtriangle.cpp +++ b/tests/manual/rhi/hellominimalcrossgfxtriangle/hellominimalcrossgfxtriangle.cpp @@ -77,7 +77,7 @@ #include <QtGui/private/qrhid3d11_p.h> #endif -#ifdef Q_OS_DARWIN +#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) #include <QtGui/private/qrhimetal_p.h> #endif @@ -283,7 +283,7 @@ void Window::init() } #endif -#ifdef Q_OS_DARWIN +#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) if (graphicsApi == Metal) { QRhiMetalInitParams params; m_r = QRhi::create(QRhi::Metal, ¶ms); @@ -483,7 +483,7 @@ int main(int argc, char **argv) // Defaults. #if defined(Q_OS_WIN) graphicsApi = D3D11; -#elif defined(Q_OS_DARWIN) +#elif defined(Q_OS_MACOS) || defined(Q_OS_IOS) graphicsApi = Metal; #elif QT_CONFIG(vulkan) graphicsApi = Vulkan; diff --git a/tests/manual/rhi/multiwindow/multiwindow.cpp b/tests/manual/rhi/multiwindow/multiwindow.cpp index 4d5de16a58..5fb5bb22ab 100644 --- a/tests/manual/rhi/multiwindow/multiwindow.cpp +++ b/tests/manual/rhi/multiwindow/multiwindow.cpp @@ -78,7 +78,7 @@ #include <QtGui/private/qrhid3d11_p.h> #endif -#ifdef Q_OS_DARWIN +#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) #include <QtGui/private/qrhimetal_p.h> #endif @@ -148,7 +148,7 @@ void createRhi() } #endif -#ifdef Q_OS_DARWIN +#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) if (graphicsApi == Metal) { QRhiMetalInitParams params; r.r = QRhi::create(QRhi::Metal, ¶ms); @@ -530,7 +530,7 @@ int main(int argc, char **argv) #if defined(Q_OS_WIN) graphicsApi = D3D11; -#elif defined(Q_OS_DARWIN) +#elif defined(Q_OS_MACOS) || defined(Q_OS_IOS) graphicsApi = Metal; #elif QT_CONFIG(vulkan) graphicsApi = Vulkan; diff --git a/tests/manual/rhi/multiwindow_threaded/multiwindow_threaded.cpp b/tests/manual/rhi/multiwindow_threaded/multiwindow_threaded.cpp index 37c6cd04c3..75a1590d94 100644 --- a/tests/manual/rhi/multiwindow_threaded/multiwindow_threaded.cpp +++ b/tests/manual/rhi/multiwindow_threaded/multiwindow_threaded.cpp @@ -82,7 +82,7 @@ #include <QtGui/private/qrhid3d11_p.h> #endif -#ifdef Q_OS_DARWIN +#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) #include <QtGui/private/qrhimetal_p.h> #endif @@ -376,7 +376,7 @@ void Renderer::createRhi() } #endif -#ifdef Q_OS_DARWIN +#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) if (graphicsApi == Metal) { QRhiMetalInitParams params; r = QRhi::create(QRhi::Metal, ¶ms, rhiFlags); @@ -730,7 +730,7 @@ int main(int argc, char **argv) #if defined(Q_OS_WIN) graphicsApi = D3D11; -#elif defined(Q_OS_DARWIN) +#elif defined(Q_OS_MACOS) || defined(Q_OS_IOS) graphicsApi = Metal; #elif QT_CONFIG(vulkan) graphicsApi = Vulkan; diff --git a/tests/manual/rhi/offscreen/offscreen.cpp b/tests/manual/rhi/offscreen/offscreen.cpp index 79e50d3dd4..31c0632be1 100644 --- a/tests/manual/rhi/offscreen/offscreen.cpp +++ b/tests/manual/rhi/offscreen/offscreen.cpp @@ -72,7 +72,7 @@ #include <QtGui/private/qrhid3d11_p.h> #endif -#ifdef Q_OS_DARWIN +#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) #include <QtGui/private/qrhimetal_p.h> #endif @@ -130,7 +130,7 @@ int main(int argc, char **argv) #if defined(Q_OS_WIN) graphicsApi = D3D11; -#elif defined(Q_OS_DARWIN) +#elif defined(Q_OS_MACOS) || defined(Q_OS_IOS) graphicsApi = Metal; #elif QT_CONFIG(vulkan) graphicsApi = Vulkan; @@ -217,7 +217,7 @@ int main(int argc, char **argv) } #endif -#ifdef Q_OS_DARWIN +#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) if (graphicsApi == Metal) { QRhiMetalInitParams params; r = QRhi::create(QRhi::Metal, ¶ms); diff --git a/tests/manual/rhi/shared/examplefw.h b/tests/manual/rhi/shared/examplefw.h index bfe1ee6d2b..dc388274d7 100644 --- a/tests/manual/rhi/shared/examplefw.h +++ b/tests/manual/rhi/shared/examplefw.h @@ -78,7 +78,7 @@ #include <QtGui/private/qrhid3d11_p.h> #endif -#ifdef Q_OS_DARWIN +#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) #include <QtGui/private/qrhimetal_p.h> #endif @@ -292,7 +292,7 @@ void Window::init() } #endif -#ifdef Q_OS_DARWIN +#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) if (graphicsApi == Metal) { QRhiMetalInitParams params; m_r = QRhi::create(QRhi::Metal, ¶ms, rhiFlags); @@ -445,7 +445,7 @@ int main(int argc, char **argv) // Defaults. #if defined(Q_OS_WIN) graphicsApi = D3D11; -#elif defined(Q_OS_DARWIN) +#elif defined(Q_OS_MACOS) || defined(Q_OS_IOS) graphicsApi = Metal; #elif QT_CONFIG(vulkan) graphicsApi = Vulkan; diff --git a/tests/manual/rhi/texuploads/texuploads.cpp b/tests/manual/rhi/texuploads/texuploads.cpp index 4c10a6b965..091e47b9ea 100644 --- a/tests/manual/rhi/texuploads/texuploads.cpp +++ b/tests/manual/rhi/texuploads/texuploads.cpp @@ -239,7 +239,7 @@ void Window::customRender() if (d.testStage == 6) { const QRhiNativeHandles *h = d.tex->nativeHandles(); if (h) { -#ifdef Q_OS_DARWIN +#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) if (graphicsApi == Metal) { qDebug() << "Metal texture: " << static_cast<const QRhiMetalTextureNativeHandles *>(h)->texture; // Now could cast to id<MTLTexture> and do something with diff --git a/util/unicode/README b/util/unicode/README index 29594b6caa..0a3926906d 100644 --- a/util/unicode/README +++ b/util/unicode/README @@ -37,6 +37,9 @@ To update: the same time and update text/qt_attribution.json to match; use the UCD Revision number, rather than the Unicode standard number, as the Version, for all that qunicodetables.cpp uses the latter. +* If there are enum additions in qchar.h (public API), be sure to also + update the documentation in qchar.cpp for each affected enum, + respecting the existing ordering. * If you don't normally build in the source tree, remember to delete qtbase/.qmake.stash while you're cleaning up. diff --git a/util/unicode/main.cpp b/util/unicode/main.cpp index c3465b3045..9826775034 100644 --- a/util/unicode/main.cpp +++ b/util/unicode/main.cpp @@ -193,9 +193,9 @@ enum Direction { DirLRI = QChar::DirLRI, DirRLI = QChar::DirRLI, DirFSI = QChar::DirFSI, - DirPDI = QChar::DirPDI + DirPDI = QChar::DirPDI, - , Dir_Unassigned + Dir_Unassigned }; static QHash<QByteArray, Direction> directionMap; @@ -245,9 +245,9 @@ enum JoiningType { Joining_Dual, Joining_Right, Joining_Left, - Joining_Transparent + Joining_Transparent, - , Joining_Unassigned + Joining_Unassigned }; static QHash<QByteArray, JoiningType> joining_map; @@ -294,7 +294,8 @@ static const char *grapheme_break_class_string = " Graphemebreak_E_Modifier,\n" " Graphemebreak_Glue_After_Zwj,\n" " Graphemebreak_E_Base_GAZ,\n" - " NumGraphemeBreakClasses,\n" + "\n" + " NumGraphemeBreakClasses\n" "};\n\n"; enum GraphemeBreakClass { @@ -381,7 +382,8 @@ static const char *word_break_class_string = " WordBreak_Glue_After_Zwj,\n" " WordBreak_E_Base_GAZ,\n" " WordBreak_WSegSpace,\n" - " NumWordBreakClasses,\n" + "\n" + " NumWordBreakClasses\n" "};\n\n"; enum WordBreakClass { @@ -469,6 +471,7 @@ static const char *sentence_break_class_string = " SentenceBreak_SContinue,\n" " SentenceBreak_STerm,\n" " SentenceBreak_Close,\n" + "\n" " NumSentenceBreakClasses\n" "};\n\n"; @@ -486,9 +489,9 @@ enum SentenceBreakClass { SentenceBreak_ATerm, SentenceBreak_SContinue, SentenceBreak_STerm, - SentenceBreak_Close + SentenceBreak_Close, - , SentenceBreak_Unassigned + SentenceBreak_Unassigned }; static QHash<QByteArray, SentenceBreakClass> sentence_break_map; @@ -537,6 +540,7 @@ static const char *line_break_class_string = " LineBreak_EB, LineBreak_EM, LineBreak_ZWJ,\n" " LineBreak_SA, LineBreak_SG, LineBreak_SP,\n" " LineBreak_CR, LineBreak_LF, LineBreak_BK,\n" + "\n" " NumLineBreakClasses\n" "};\n\n"; |