Merge remote-tracking branch 'origin/5.15' into dev
Change-Id: I99ee6f8b4bdc372437ee60d1feab931487fe55c4
This commit is contained in:
commit
2a4b957789
@ -32,84 +32,103 @@ manifestmeta.filters = highlighted android thumbnail ios
|
||||
|
||||
manifestmeta.highlighted.attributes = isHighlighted:true
|
||||
|
||||
manifestmeta.android.names = "QtQuick/Qt Quick Demo - Calqlatr" \
|
||||
"QtWidgets/Application Chooser Example" \
|
||||
"QtWidgets/Stickman Example" \
|
||||
"QtWidgets/Move Blocks Example" \
|
||||
"QtWidgets/Border Layout Example" \
|
||||
"QtWidgets/Flow Layout Example" \
|
||||
"QtWidgets/Dock Widgets Example" \
|
||||
"QtWidgets/Recent Files Example" \
|
||||
"QtWidgets/Concentric Circles Example" \
|
||||
"QtWidgets/Gradients" \
|
||||
"QtWidgets/Font Sampler Example" \
|
||||
"QtWidgets/Path Stroking" \
|
||||
"QtWidgets/Transformations Example" \
|
||||
"QtWidgets/Syntax Highlighter Example" \
|
||||
"QtWidgets/Calendar Example" \
|
||||
"QtWidgets/Analog Clock Example" \
|
||||
"QtWidgets/Calculator Example" \
|
||||
"QtWidgets/Mouse Button Tester" \
|
||||
"QtWidgets/Character Map Example" \
|
||||
"QtWidgets/Digital Clock Example" \
|
||||
"QtWidgets/Elided Label Example" \
|
||||
"QtWidgets/Sliders Example" \
|
||||
"QtWidgets/Tetrix Example" \
|
||||
"QtWidgets/Group Box Example" \
|
||||
"QtWidgets/Undo Framework" \
|
||||
"QtWidgets/Colliding Mice Example" \
|
||||
"QtWidgets/Diagram Scene Example" \
|
||||
"QtWidgets/Elastic Nodes Example" \
|
||||
"QtWidgets/Weather Anchor Layout Example" \
|
||||
"QtNetwork/Torrent Example" \
|
||||
"QtNetwork/Network Chat Example" \
|
||||
"QtSQL/Master Detail Example" \
|
||||
"QtLinguist/Arrow Pad Example" \
|
||||
"QtGui/Raster Window Example" \
|
||||
"QtGui/Analog Clock Window Example" \
|
||||
"QtAndroidExtras/Qt Notifier" \
|
||||
"QtMultimedia/QML Video Shader Effects Example" \
|
||||
"QtMultimedia/QML Video Example" \
|
||||
"QtMultimedia/QML Camera Example" \
|
||||
"QtSVG/Text Object Example" \
|
||||
"QtQML/Qt Quick Examples - XMLHttpRequest" \
|
||||
"QtQuick/Qt Quick Particles Examples - *" \
|
||||
"QtQuick/Qt Quick Examples - Touch Interaction" \
|
||||
"QtQuick/Scene Graph - Custom Geometry" \
|
||||
"QtQuick/Scene Graph - Graph" \
|
||||
"QtQuick/Scene Graph - OpenGL Under QML" \
|
||||
"QtQuick/Scene Graph - Painted Item" \
|
||||
"QtQuick/Scene Graph - Rendering FBOs" \
|
||||
"QtQuick/Scene Graph - Simple Material" \
|
||||
"QtQuick/Qt Quick Examples - Image Elements" \
|
||||
"QtQuick/Qt Quick Examples - Key Interaction" \
|
||||
"QtQuick/Qt Quick Examples - Text" \
|
||||
"QtQuick/Qt Quick Examples - Animation" \
|
||||
"QtQuick/Qt Quick Examples - Shader Effects" \
|
||||
"QtQuick/Qt Quick Examples - Canvas" \
|
||||
"QtQuick/Qt Quick Examples - MouseArea" \
|
||||
"QtQuick/Qt Quick Examples - Positioners" \
|
||||
"QtQuick/Qt Quick Examples - Right to Left" \
|
||||
"QtWidgets/Interview" \
|
||||
"QtWidgets/Spreadsheet" \
|
||||
"QtWidgets/Pixelator Example" \
|
||||
"QtWidgets/Animated Tiles Example" \
|
||||
"QtWidgets/Affine Transformations" \
|
||||
"QtWidgets/Image Composition Example" \
|
||||
"QtWidgets/Basic Drawing Example" \
|
||||
"QtWidgets/Vector Deformation" \
|
||||
"QtWidgets/Painter Paths Example" \
|
||||
"QtWidgets/Style Sheet Example" \
|
||||
"QtWidgets/Code Editor Example" \
|
||||
"QtWidgets/Scribble Example" \
|
||||
"QtWidgets/Line Edits Example" \
|
||||
"QtWidgets/Calendar Widget Example" \
|
||||
"QtWidgets/Completer Example" \
|
||||
"QtWidgets/I18N Example" \
|
||||
"QtQML/Extending QML - Grouped Properties Example" \
|
||||
"QtQML/Extending QML - Methods Example" \
|
||||
"QtQML/Extending QML - Signal Support Example" \
|
||||
"QtQML/Extending QML - Attached Properties Example"
|
||||
manifestmeta.android.names = "Qt3D/Qt 3D: Basic Shapes C++ Example" \
|
||||
"Qt3D/Qt 3D: Planets QML Example" \
|
||||
"Qt3D/Qt 3D: Simple Custom Material QML Example" \
|
||||
"QtAndroidExtras/Qt Notifier" \
|
||||
"QtBluetooth/Bluetooth Low Energy Scanner Example" \
|
||||
"QtBluetooth/Bluetooth Scanner Example" \
|
||||
"QtBluetooth/QML Bluetooth Scanner Example" \
|
||||
"QtCharts/*" \
|
||||
"QtConcurrent/QtConcurrent Progress Dialog Example" \
|
||||
"QtDataVisualization/Audiolevels Example" \
|
||||
"QtDataVisualization/Qt Quick 2 Scatter Example" \
|
||||
"QtDataVisualization/Qt Quick 2 Surface Multiseries Example" \
|
||||
"QtGui/Analog Clock Window Example" \
|
||||
"QtGui/OpenGL Window Example" \
|
||||
"QtGui/Raster Window Example" \
|
||||
"QtLinguist/Arrow Pad Example" \
|
||||
"QtLinguistManual/Hello tr() Example" \
|
||||
"QtLocation/Map Viewer (QML)" \
|
||||
"QtLocation/Places Map (QML)" \
|
||||
"QtLocation/Plane Spotter (QML)" \
|
||||
"QtMultimedia/AudioEngine Example" \
|
||||
"QtMultimedia/Camera Example" \
|
||||
"QtMultimedia/QML Camera Example" \
|
||||
"QtMultimedia/QML Video Example" \
|
||||
"QtMultimedia/QML Video Shader Effects Example" \
|
||||
"QtNFC/Annotated URL Example" \
|
||||
"QtNFC/QML Poster Example" \
|
||||
"QtOpenGL/2D Painting Example" \
|
||||
"QtOpenGL/Hello GLES3 Example" \
|
||||
"QtOpenGL/Textures Example" \
|
||||
"QtPositioning/SatelliteInfo (C++/QML)" \
|
||||
"QtPositioning/Weather Info (C++/QML)" \
|
||||
"QtPurchasing/Qt Purchasing Examples - QtHangman" \
|
||||
"QtQML/Extending QML - Attached Properties Example" \
|
||||
"QtQML/Extending QML - Grouped Properties Example" \
|
||||
"QtQML/Extending QML - Methods Example" \
|
||||
"QtQML/Extending QML - Signal Support Example" \
|
||||
"QtQML/Qt Quick Examples - XMLHttpRequest" \
|
||||
"QtQml/Qt Quick Examples - XMLHttpRequest" \
|
||||
"QtQuick/*" \
|
||||
"QtQuickControls/*" \
|
||||
"QtQuickControls1/Qt Quick Controls 1 - Calendar Example" \
|
||||
"QtQuickControls1/Qt Quick Controls 1 - Gallery" \
|
||||
"QtQuickControls1/Qt Quick Controls 1 - Styles Example" \
|
||||
"QtQuickControls1/Qt Quick Controls 1 - Table View Example" \
|
||||
"QtQuickControls1/Qt Quick Controls 1 - Touch Gallery" \
|
||||
"QtQuickDialogs/*" \
|
||||
"QtQuickExtras/*" \
|
||||
"QtSCXML/Qt SCXML Calculator QML Example" \
|
||||
"QtSCXML/Qt SCXML Sudoku Example" \
|
||||
"QtSCXML/Qt SCXML Traffic Light Example (Dynamic)" \
|
||||
"QtSCXML/Qt SCXML Traffic Light QML Example (Dynamic)" \
|
||||
"QtSQL/Master Detail Example" \
|
||||
"QtSVG/Text Object Example" \
|
||||
"QtUiTools/Text Finder Example" \
|
||||
"QtWebView/Qt WebView Examples - Minibrowser" \
|
||||
"QtWidgets/Address Book Example" \
|
||||
"QtWidgets/Affine Transformations" \
|
||||
"QtWidgets/Analog Clock Example" \
|
||||
"QtWidgets/Animated Tiles Example" \
|
||||
"QtWidgets/Application Chooser Example" \
|
||||
"QtWidgets/Basic Layouts Example" \
|
||||
"QtWidgets/Border Layout Example" \
|
||||
"QtWidgets/Code Editor Example" \
|
||||
"QtWidgets/Colliding Mice Example" \
|
||||
"QtWidgets/Concentric Circles Example" \
|
||||
"QtWidgets/Digital Clock Example" \
|
||||
"QtWidgets/Dynamic Layouts Example" \
|
||||
"QtWidgets/Easing Curves Example" \
|
||||
"QtWidgets/Editable Tree Model Example" \
|
||||
"QtWidgets/Elided Label Example" \
|
||||
"QtWidgets/Event Transitions Example" \
|
||||
"QtWidgets/Fade Message Effect Example" \
|
||||
"QtWidgets/Flow Layout Example" \
|
||||
"QtWidgets/Font Sampler Example" \
|
||||
"QtWidgets/Frozen Column Example" \
|
||||
"QtWidgets/Gradients" \
|
||||
"QtWidgets/Group Box Example" \
|
||||
"QtWidgets/Image Composition Example" \
|
||||
"QtWidgets/Line Edits Example" \
|
||||
"QtWidgets/Mouse Button Tester" \
|
||||
"QtWidgets/Move Blocks Example" \
|
||||
"QtWidgets/Painter Paths Example" \
|
||||
"QtWidgets/Painter Paths Example" \
|
||||
"QtWidgets/Path Stroking" \
|
||||
"QtWidgets/Pixelator Example" \
|
||||
"QtWidgets/Recent Files Example" \
|
||||
"QtWidgets/SDI Example" \
|
||||
"QtWidgets/Scribble Example" \
|
||||
"QtWidgets/Simple Tree Model Example" \
|
||||
"QtWidgets/Sliders Example" \
|
||||
"QtWidgets/Spreadsheet" \
|
||||
"QtWidgets/Touch Dials Example" \
|
||||
"QtWidgets/Transformations Example" \
|
||||
"QtWidgets/Undo Framework" \
|
||||
"QtWidgets/Vector Deformation" \
|
||||
"QtWidgets/Wiggly Example"
|
||||
|
||||
manifestmeta.android.tags = android
|
||||
|
||||
|
@ -81,7 +81,11 @@ int main(int argc, char *argv[])
|
||||
const QRect availableSize = httpWin.screen()->availableGeometry();
|
||||
httpWin.resize(availableSize.width() / 5, availableSize.height() / 5);
|
||||
httpWin.move((availableSize.width() - httpWin.width()) / 2, (availableSize.height() - httpWin.height()) / 2);
|
||||
|
||||
#ifdef Q_OS_ANDROID
|
||||
httpWin.showMaximized();
|
||||
#else
|
||||
httpWin.show();
|
||||
#endif
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
@ -58,6 +58,9 @@ static constexpr int MouseCount = 7;
|
||||
//! [0]
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
#ifdef Q_OS_ANDROID
|
||||
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
#endif
|
||||
QApplication app(argc, argv);
|
||||
//! [0]
|
||||
|
||||
|
@ -55,6 +55,9 @@
|
||||
int main(int argv, char *args[])
|
||||
{
|
||||
Q_INIT_RESOURCE(diagramscene);
|
||||
#ifdef Q_OS_ANDROID
|
||||
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
#endif
|
||||
|
||||
QApplication app(argv, args);
|
||||
MainWindow mainWindow;
|
||||
|
@ -55,6 +55,9 @@
|
||||
//! [0]
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#ifdef Q_OS_ANDROID
|
||||
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
#endif
|
||||
QApplication app(argc, argv);
|
||||
MainWindow mw;
|
||||
mw.show();
|
||||
|
@ -56,6 +56,10 @@
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
Q_INIT_RESOURCE(spreadsheet);
|
||||
#ifdef Q_OS_ANDROID
|
||||
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
#endif
|
||||
|
||||
QApplication app(argc, argv);
|
||||
SpreadSheet sheet(10, 6);
|
||||
sheet.setWindowIcon(QPixmap(":/images/interview.png"));
|
||||
|
@ -56,7 +56,11 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
Dialog dialog;
|
||||
#ifdef Q_OS_ANDROID
|
||||
dialog.showMaximized();
|
||||
#else
|
||||
dialog.show();
|
||||
#endif
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
@ -56,6 +56,11 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
Dialog dialog;
|
||||
#ifdef Q_OS_ANDROID
|
||||
dialog.showMaximized();
|
||||
#else
|
||||
dialog.show();
|
||||
#endif
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
@ -58,6 +58,9 @@
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
Q_INIT_RESOURCE(application);
|
||||
#ifdef Q_OS_ANDROID
|
||||
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
#endif
|
||||
|
||||
QApplication app(argc, argv);
|
||||
QCoreApplication::setOrganizationName("QtProject");
|
||||
|
@ -54,6 +54,9 @@
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#ifdef Q_OS_ANDROID
|
||||
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
#endif
|
||||
QApplication app(argc, argv);
|
||||
Q_INIT_RESOURCE(dockwidgets);
|
||||
MainWindow mainWin;
|
||||
|
@ -55,7 +55,9 @@
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
Q_INIT_RESOURCE(affine);
|
||||
|
||||
#ifdef Q_OS_ANDROID
|
||||
qputenv("QT_SCALE_FACTOR", "2");
|
||||
#endif
|
||||
QApplication app(argc, argv);
|
||||
|
||||
XFormWidget xformWidget(nullptr);
|
||||
|
@ -787,8 +787,8 @@ XFormWidget::XFormWidget(QWidget *parent)
|
||||
view = new XFormView(this);
|
||||
view->setMinimumSize(200, 200);
|
||||
|
||||
QGroupBox *mainGroup = new QGroupBox(this);
|
||||
mainGroup->setFixedWidth(180);
|
||||
QWidget *mainContentWidget = new QWidget();
|
||||
QGroupBox *mainGroup = new QGroupBox(mainContentWidget);
|
||||
mainGroup->setTitle(tr("Affine Transformations"));
|
||||
|
||||
QGroupBox *rotateGroup = new QGroupBox(mainGroup);
|
||||
@ -837,10 +837,6 @@ XFormWidget::XFormWidget(QWidget *parent)
|
||||
whatsThisButton->setText(tr("What's This?"));
|
||||
whatsThisButton->setCheckable(true);
|
||||
|
||||
QHBoxLayout *viewLayout = new QHBoxLayout(this);
|
||||
viewLayout->addWidget(view);
|
||||
viewLayout->addWidget(mainGroup);
|
||||
|
||||
QVBoxLayout *rotateGroupLayout = new QVBoxLayout(rotateGroup);
|
||||
rotateGroupLayout->addWidget(rotateSlider);
|
||||
|
||||
@ -871,6 +867,20 @@ XFormWidget::XFormWidget(QWidget *parent)
|
||||
#endif
|
||||
mainGroupLayout->addWidget(whatsThisButton);
|
||||
|
||||
mainGroup->setLayout(mainGroupLayout);
|
||||
|
||||
QVBoxLayout *mainContentLayout = new QVBoxLayout();
|
||||
mainContentLayout->addWidget(mainGroup);
|
||||
mainContentWidget->setLayout(mainContentLayout);
|
||||
|
||||
QScrollArea *mainScrollArea = new QScrollArea();
|
||||
mainScrollArea->setWidget(mainContentWidget);
|
||||
mainScrollArea->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
|
||||
|
||||
QHBoxLayout *viewLayout = new QHBoxLayout(this);
|
||||
viewLayout->addWidget(view);
|
||||
viewLayout->addWidget(mainScrollArea);
|
||||
|
||||
connect(rotateSlider, &QSlider::valueChanged, view, &XFormView::changeRotation);
|
||||
connect(shearSlider, &QSlider::valueChanged, view, &XFormView::changeShear);
|
||||
connect(scaleSlider, &QSlider::valueChanged, view, &XFormView::changeScale);
|
||||
|
@ -54,6 +54,9 @@
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#ifdef Q_OS_ANDROID
|
||||
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
#endif
|
||||
QApplication app(argc, argv);
|
||||
Window window;
|
||||
window.show();
|
||||
|
@ -54,6 +54,9 @@
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#ifdef Q_OS_ANDROID
|
||||
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
#endif
|
||||
QApplication app(argc, argv);
|
||||
MainWindow window;
|
||||
window.show();
|
||||
|
@ -282,7 +282,8 @@ GradientWidget::GradientWidget(QWidget *parent)
|
||||
|
||||
m_renderer = new GradientRenderer(this);
|
||||
|
||||
QGroupBox *mainGroup = new QGroupBox(this);
|
||||
QWidget *mainContentWidget = new QWidget();
|
||||
QGroupBox *mainGroup = new QGroupBox(mainContentWidget);
|
||||
mainGroup->setTitle(tr("Gradients"));
|
||||
|
||||
QGroupBox *editorGroup = new QGroupBox(mainGroup);
|
||||
@ -327,11 +328,6 @@ GradientWidget::GradientWidget(QWidget *parent)
|
||||
whatsThisButton->setText(tr("What's This?"));
|
||||
whatsThisButton->setCheckable(true);
|
||||
|
||||
// Layouts
|
||||
QHBoxLayout *mainLayout = new QHBoxLayout(this);
|
||||
mainLayout->addWidget(m_renderer);
|
||||
mainLayout->addWidget(mainGroup);
|
||||
|
||||
mainGroup->setFixedWidth(200);
|
||||
QVBoxLayout *mainGroupLayout = new QVBoxLayout(mainGroup);
|
||||
mainGroupLayout->addWidget(editorGroup);
|
||||
@ -370,6 +366,21 @@ GradientWidget::GradientWidget(QWidget *parent)
|
||||
defaultsGroupLayout->addWidget(default3Button);
|
||||
editorGroupLayout->addWidget(default4Button);
|
||||
|
||||
mainGroup->setLayout(mainGroupLayout);
|
||||
|
||||
QVBoxLayout *mainContentLayout = new QVBoxLayout();
|
||||
mainContentLayout->addWidget(mainGroup);
|
||||
mainContentWidget->setLayout(mainContentLayout);
|
||||
|
||||
QScrollArea *mainScrollArea = new QScrollArea();
|
||||
mainScrollArea->setWidget(mainContentWidget);
|
||||
mainScrollArea->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
|
||||
|
||||
// Layouts
|
||||
QHBoxLayout *mainLayout = new QHBoxLayout(this);
|
||||
mainLayout->addWidget(m_renderer);
|
||||
mainLayout->addWidget(mainScrollArea);
|
||||
|
||||
connect(m_editor, &GradientEditor::gradientStopsChanged,
|
||||
m_renderer, &GradientRenderer::setGradientStops);
|
||||
connect(m_linearButton, &QRadioButton::clicked,
|
||||
|
@ -55,6 +55,9 @@
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
Q_INIT_RESOURCE(gradients);
|
||||
#ifdef Q_OS_ANDROID
|
||||
qputenv("QT_SCALE_FACTOR", "2");
|
||||
#endif
|
||||
|
||||
QApplication app(argc, argv);
|
||||
|
||||
|
@ -55,6 +55,9 @@
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
Q_INIT_RESOURCE(pathstroke);
|
||||
#ifdef Q_OS_ANDROID
|
||||
qputenv("QT_SCALE_FACTOR", "2");
|
||||
#endif
|
||||
|
||||
QApplication app(argc, argv);
|
||||
|
||||
|
@ -54,6 +54,9 @@
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
Q_INIT_RESOURCE(undo);
|
||||
#ifdef Q_OS_ANDROID
|
||||
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
#endif
|
||||
|
||||
QApplication app(argc, argv);
|
||||
|
||||
|
@ -54,6 +54,9 @@
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#ifdef Q_OS_ANDROID
|
||||
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
#endif
|
||||
QApplication app(argc, argv);
|
||||
Calculator calc;
|
||||
calc.show();
|
||||
|
@ -55,6 +55,9 @@
|
||||
//! [0]
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
#ifdef Q_OS_ANDROID
|
||||
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
#endif
|
||||
QApplication application( argc, argv );
|
||||
TestWidget w;
|
||||
w.showFullScreen();
|
||||
|
@ -54,6 +54,9 @@
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#ifdef Q_OS_ANDROID
|
||||
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
#endif
|
||||
QApplication app(argc, argv);
|
||||
MainWindow window;
|
||||
window.show();
|
||||
|
@ -54,6 +54,9 @@
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#ifdef Q_OS_ANDROID
|
||||
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
#endif
|
||||
QApplication app(argc, argv);
|
||||
Window window;
|
||||
window.show();
|
||||
|
@ -131,7 +131,7 @@ void RSSListing::get(const QUrl &url)
|
||||
currentReply = manager.get(request);
|
||||
connect(currentReply, SIGNAL(readyRead()), this, SLOT(readyRead()));
|
||||
connect(currentReply, SIGNAL(metaDataChanged()), this, SLOT(metaDataChanged()));
|
||||
connect(currentReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(error(QNetworkReply::NetworkError)));
|
||||
connect(currentReply, SIGNAL(errorOccurred(QNetworkReply::NetworkError)), this, SLOT(error(QNetworkReply::NetworkError)));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -20,11 +20,11 @@ qtConfig(c++1z): CONFIG += c++1z
|
||||
qtConfig(c++2a): CONFIG += c++2a
|
||||
qtConfig(c99): CONFIG += c99
|
||||
qtConfig(c11): CONFIG += c11
|
||||
qtConfig(separate_debug_info): CONFIG += separate_debug_info
|
||||
qtConfig(stack-protector-strong): CONFIG += stack_protector_strong
|
||||
contains(TEMPLATE, .*lib) {
|
||||
# module and plugins
|
||||
unix:qtConfig(reduce_relocations): CONFIG += bsymbolic_functions
|
||||
qtConfig(separate_debug_info): CONFIG += separate_debug_info
|
||||
|
||||
!isEmpty(_QMAKE_SUPER_CACHE_): \
|
||||
rplbase = $$dirname(_QMAKE_SUPER_CACHE_)/[^/][^/]*
|
||||
|
@ -147,7 +147,7 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
/*!
|
||||
\since 5.15
|
||||
\fn qfloat16::copySign(qfloat16 sign) const noexcept
|
||||
\fn qfloat16 qfloat16::copySign(qfloat16 sign) const noexcept
|
||||
|
||||
Returns a qfloat16 with the sign of \a sign but the rest of its value taken
|
||||
from this qfloat16. Serves as qfloat16's equivalent of std::copysign().
|
||||
|
@ -884,7 +884,11 @@ void QEventDispatcherWin32::unregisterEventNotifier(QWinEventNotifier *notifier)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
doUnregisterEventNotifier(notifier);
|
||||
}
|
||||
|
||||
void QEventDispatcherWin32::doUnregisterEventNotifier(QWinEventNotifier *notifier)
|
||||
{
|
||||
Q_D(QEventDispatcherWin32);
|
||||
|
||||
int i = d->winEventNotifierList.indexOf(notifier);
|
||||
@ -996,6 +1000,10 @@ void QEventDispatcherWin32::closingDown()
|
||||
doUnregisterSocketNotifier((*(d->sn_except.begin()))->obj);
|
||||
Q_ASSERT(d->active_fd.isEmpty());
|
||||
|
||||
// clean up any eventnotifiers
|
||||
while (!d->winEventNotifierList.isEmpty())
|
||||
doUnregisterEventNotifier(d->winEventNotifierList.first());
|
||||
|
||||
// clean up any timers
|
||||
for (int i = 0; i < d->timerVec.count(); ++i)
|
||||
d->unregisterTimer(d->timerVec.at(i));
|
||||
|
@ -110,6 +110,7 @@ protected:
|
||||
QEventDispatcherWin32(QEventDispatcherWin32Private &dd, QObject *parent = 0);
|
||||
virtual void sendPostedEvents();
|
||||
void doUnregisterSocketNotifier(QSocketNotifier *notifier);
|
||||
void doUnregisterEventNotifier(QWinEventNotifier *notifier);
|
||||
|
||||
private:
|
||||
friend LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp);
|
||||
|
@ -198,11 +198,8 @@ void QWinEventNotifier::setEnabled(bool enable)
|
||||
d->enabled = enable;
|
||||
|
||||
QAbstractEventDispatcher *eventDispatcher = d->threadData.loadRelaxed()->eventDispatcher.loadRelaxed();
|
||||
if (!eventDispatcher) { // perhaps application is shutting down
|
||||
if (!enable && d->waitHandle != nullptr)
|
||||
d->unregisterWaitObject();
|
||||
if (!eventDispatcher) // perhaps application is shutting down
|
||||
return;
|
||||
}
|
||||
if (Q_UNLIKELY(thread() != QThread::currentThread())) {
|
||||
qWarning("QWinEventNotifier: Event notifiers cannot be enabled or disabled from another thread");
|
||||
return;
|
||||
|
@ -664,7 +664,15 @@ QMimeXMLProvider::QMimeXMLProvider(QMimeDatabasePrivate *db, InternalDatabaseEnu
|
||||
|
||||
load(data, size);
|
||||
}
|
||||
#endif
|
||||
#else // !QT_CONFIG(mimetype_database)
|
||||
// never called in release mode, but some debug builds may need
|
||||
// this to be defined.
|
||||
QMimeXMLProvider::QMimeXMLProvider(QMimeDatabasePrivate *db, InternalDatabaseEnum)
|
||||
: QMimeProviderBase(db, QString())
|
||||
{
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
#endif // QT_CONFIG(mimetype_database)
|
||||
|
||||
QMimeXMLProvider::QMimeXMLProvider(QMimeDatabasePrivate *db, const QString &directory)
|
||||
: QMimeProviderBase(db, directory)
|
||||
|
@ -135,13 +135,10 @@ public:
|
||||
enum InternalDatabaseEnum { InternalDatabase };
|
||||
#if QT_CONFIG(mimetype_database)
|
||||
enum : bool { InternalDatabaseAvailable = true };
|
||||
QMimeXMLProvider(QMimeDatabasePrivate *db, InternalDatabaseEnum);
|
||||
#else
|
||||
enum : bool { InternalDatabaseAvailable = false };
|
||||
QMimeXMLProvider(QMimeDatabasePrivate *db, InternalDatabaseEnum)
|
||||
: QMimeProviderBase(db, QString())
|
||||
{ Q_UNREACHABLE(); };
|
||||
#endif
|
||||
QMimeXMLProvider(QMimeDatabasePrivate *db, InternalDatabaseEnum);
|
||||
QMimeXMLProvider(QMimeDatabasePrivate *db, const QString &directory);
|
||||
~QMimeXMLProvider();
|
||||
|
||||
|
@ -7626,7 +7626,10 @@ static ResultList splitString(const StringSource &source, const QChar *sep,
|
||||
#if QT_DEPRECATED_SINCE(5, 15)
|
||||
Qt::SplitBehavior mapSplitBehavior(QString::SplitBehavior sb)
|
||||
{
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_DEPRECATED
|
||||
return sb & QString::SkipEmptyParts ? Qt::SkipEmptyParts : Qt::KeepEmptyParts;
|
||||
QT_WARNING_POP
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1383,6 +1383,10 @@ QT_WARNING_POP
|
||||
|
||||
If the datetime is invalid, an empty string will be returned.
|
||||
|
||||
\note If localized month and day names are desired, please switch to using
|
||||
QLocale::system().toString() as QDate methods shall change to use English (C
|
||||
locale) names at Qt 6.
|
||||
|
||||
\sa fromString(), QDateTime::toString(), QTime::toString(), QLocale::toString()
|
||||
|
||||
*/
|
||||
@ -1884,6 +1888,10 @@ QT_WARNING_POP
|
||||
|
||||
\snippet code/src_corelib_tools_qdatetime.cpp 3
|
||||
|
||||
\note If localized month and day names are used, please switch to using
|
||||
QLocale::system().toDate() as QDate methods shall change to only recognize
|
||||
English (C locale) names at Qt 6.
|
||||
|
||||
\sa toString(), QDateTime::fromString(), QTime::fromString(),
|
||||
QLocale::toDate()
|
||||
*/
|
||||
@ -2244,6 +2252,10 @@ QT_WARNING_POP
|
||||
If the time is invalid, an empty string will be returned.
|
||||
If \a format is empty, the default format "hh:mm:ss" is used.
|
||||
|
||||
\note If localized forms of am or pm (the AP, ap, A or a formats) are
|
||||
desired, please switch to using QLocale::system().toString() as QTime
|
||||
methods shall change to use English (C locale) at Qt 6.
|
||||
|
||||
\sa fromString(), QDate::toString(), QDateTime::toString(), QLocale::toString()
|
||||
*/
|
||||
QString QTime::toString(QStringView format) const
|
||||
@ -2641,6 +2653,10 @@ QT_WARNING_POP
|
||||
|
||||
\snippet code/src_corelib_tools_qdatetime.cpp 8
|
||||
|
||||
\note If localized forms of am or pm (the AP, ap, A or a formats) are used,
|
||||
please switch to using QLocale::system().toTime() as QTime methods shall
|
||||
change to only recognize English (C locale) at Qt 6.
|
||||
|
||||
\sa toString(), QDateTime::fromString(), QDate::fromString(),
|
||||
QLocale::toTime()
|
||||
*/
|
||||
@ -4541,6 +4557,10 @@ QT_WARNING_POP
|
||||
|
||||
If the datetime is invalid, an empty string will be returned.
|
||||
|
||||
\note If localized month and day names are desired, please switch to using
|
||||
QLocale::system().toString() as QDateTime methods shall change to use
|
||||
English (C locale) names at Qt 6.
|
||||
|
||||
\sa fromString(), QDate::toString(), QTime::toString(), QLocale::toString()
|
||||
*/
|
||||
QString QDateTime::toString(QStringView format) const
|
||||
@ -5580,6 +5600,10 @@ QT_WARNING_POP
|
||||
|
||||
\snippet code/src_corelib_tools_qdatetime.cpp 14
|
||||
|
||||
\note If localized month and day names are used, please switch to using
|
||||
QLocale::system().toDateTime() as QDateTime methods shall change to only
|
||||
recognize English (C locale) names at Qt 6.
|
||||
|
||||
\sa toString(), QDate::fromString(), QTime::fromString(),
|
||||
QLocale::toDateTime()
|
||||
*/
|
||||
|
@ -1574,7 +1574,6 @@ uint qHash(long double key, uint seed) noexcept
|
||||
*/
|
||||
|
||||
/*! \fn template <class Key, class T> int QHash<Key, T>::count(const Key &key) const
|
||||
\obsolete
|
||||
|
||||
Returns the number of items associated with the \a key.
|
||||
|
||||
@ -2693,13 +2692,6 @@ uint qHash(long double key, uint seed) noexcept
|
||||
\sa QHash::remove()
|
||||
*/
|
||||
|
||||
/*! \fn template <class Key, class T> int QMultiHash<Key, T>::count(const Key &key) const
|
||||
|
||||
Returns the number of items associated with the \a key.
|
||||
|
||||
\sa contains(), insert()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <class Key, class T> int QMultiHash<Key, T>::count(const Key &key, const T &value) const
|
||||
\since 4.3
|
||||
|
@ -309,10 +309,10 @@ public:
|
||||
QList<Key> keys(const T &value) const;
|
||||
QList<T> values() const;
|
||||
#if QT_DEPRECATED_SINCE(5, 15)
|
||||
QT_DEPRECATED_X("Use QMultiHash for hashes storing multiple values with the same key.") QList<Key> uniqueKeys() const;
|
||||
QT_DEPRECATED_X("Use QMultiHash for hashes storing multiple values with the same key.") QList<T> values(const Key &key) const;
|
||||
QT_DEPRECATED_X("Use QMultiHash for hashes storing multiple values with the same key.") int count(const Key &key) const;
|
||||
QT_DEPRECATED_VERSION_X_5_15("Use QMultiHash for hashes storing multiple values with the same key.") QList<Key> uniqueKeys() const;
|
||||
QT_DEPRECATED_VERSION_X_5_15("Use QMultiHash for hashes storing multiple values with the same key.") QList<T> values(const Key &key) const;
|
||||
#endif
|
||||
int count(const Key &key) const;
|
||||
|
||||
class const_iterator;
|
||||
|
||||
@ -512,8 +512,8 @@ public:
|
||||
iterator insert(const Key &key, const T &value);
|
||||
void insert(const QHash &hash);
|
||||
#if QT_DEPRECATED_SINCE(5, 15)
|
||||
QT_DEPRECATED_X("Use QMultiHash for hashes storing multiple values with the same key.") iterator insertMulti(const Key &key, const T &value);
|
||||
QT_DEPRECATED_X("Use QMultiHash for hashes storing multiple values with the same key.") QHash &unite(const QHash &other);
|
||||
QT_DEPRECATED_VERSION_X_5_15("Use QMultiHash for hashes storing multiple values with the same key.") iterator insertMulti(const Key &key, const T &value);
|
||||
QT_DEPRECATED_VERSION_X_5_15("Use QMultiHash for hashes storing multiple values with the same key.") QHash &unite(const QHash &other);
|
||||
#endif
|
||||
|
||||
// STL compatibility
|
||||
@ -710,6 +710,19 @@ Q_OUTOFLINE_TEMPLATE QList<T> QHash<Key, T>::values() const
|
||||
return res;
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
Q_OUTOFLINE_TEMPLATE int QHash<Key, T>::count(const Key &akey) const
|
||||
{
|
||||
int cnt = 0;
|
||||
Node *node = *findNode(akey);
|
||||
if (node != e) {
|
||||
do {
|
||||
++cnt;
|
||||
} while ((node = node->next) != e && node->key == akey);
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
Q_INLINE_TEMPLATE const T QHash<Key, T>::operator[](const Key &akey) const
|
||||
{
|
||||
@ -1053,7 +1066,6 @@ public:
|
||||
|
||||
int remove(const Key &key, const T &value);
|
||||
|
||||
int count(const Key &key) const;
|
||||
int count(const Key &key, const T &value) const;
|
||||
|
||||
QList<Key> uniqueKeys() const;
|
||||
@ -1206,12 +1218,6 @@ Q_OUTOFLINE_TEMPLATE QList<T> QHash<Key, T>::values(const Key &akey) const
|
||||
return static_cast<const QMultiHash<Key, T> *>(this)->values(akey);
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
Q_OUTOFLINE_TEMPLATE int QHash<Key, T>::count(const Key &akey) const
|
||||
{
|
||||
return static_cast<const QMultiHash<Key, T> *>(this)->count(akey);
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
Q_OUTOFLINE_TEMPLATE QList<Key> QHash<Key, T>::uniqueKeys() const
|
||||
{
|
||||
@ -1232,19 +1238,6 @@ Q_OUTOFLINE_TEMPLATE QList<T> QMultiHash<Key, T>::values(const Key &akey) const
|
||||
return res;
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
Q_OUTOFLINE_TEMPLATE int QMultiHash<Key, T>::count(const Key &akey) const
|
||||
{
|
||||
int cnt = 0;
|
||||
Node *node = *findNode(akey);
|
||||
if (node != this->e) {
|
||||
do {
|
||||
++cnt;
|
||||
} while ((node = node->next) != this->e && node->key == akey);
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
#if !defined(QT_NO_JAVA_STYLE_ITERATORS)
|
||||
template <class Key, class T>
|
||||
class QHashIterator
|
||||
|
@ -195,7 +195,6 @@ public:
|
||||
typedef typename Iterator::iterator_category iterator_category;
|
||||
typedef typename Iterator::difference_type difference_type;
|
||||
typedef std::pair<Key, T> value_type;
|
||||
typedef const value_type *pointer;
|
||||
typedef const value_type &reference;
|
||||
|
||||
QKeyValueIterator() = default;
|
||||
@ -206,6 +205,31 @@ public:
|
||||
return std::pair<Key, T>(i.key(), i.value());
|
||||
}
|
||||
|
||||
struct pointer {
|
||||
pointer(value_type&& r_)
|
||||
: r(std::move(r_))
|
||||
{}
|
||||
|
||||
pointer() = default;
|
||||
pointer(const pointer &other) = default;
|
||||
pointer(pointer &&other) = default;
|
||||
pointer& operator=(const pointer &other) = default;
|
||||
pointer& operator=(pointer &&other) = default;
|
||||
|
||||
value_type& operator*() const {
|
||||
return r;
|
||||
}
|
||||
|
||||
value_type r;
|
||||
const value_type *operator->() const {
|
||||
return &r;
|
||||
}
|
||||
};
|
||||
|
||||
pointer operator->() const {
|
||||
return pointer(std::pair<Key, T>(i.key(), i.value()));
|
||||
}
|
||||
|
||||
friend bool operator==(QKeyValueIterator lhs, QKeyValueIterator rhs) noexcept { return lhs.i == rhs.i; }
|
||||
friend bool operator!=(QKeyValueIterator lhs, QKeyValueIterator rhs) noexcept { return lhs.i != rhs.i; }
|
||||
|
||||
|
@ -57,7 +57,7 @@
|
||||
\internal
|
||||
*/
|
||||
|
||||
/*! \typedef QKeyValueIterator::pointer
|
||||
/*! \struct QKeyValueIterator::pointer
|
||||
\internal
|
||||
*/
|
||||
|
||||
@ -75,11 +75,20 @@
|
||||
Constructs a QKeyValueIterator on top of \a o.
|
||||
*/
|
||||
|
||||
/*! \fn template<typename Key, typename T, class Iterator> const T &QKeyValueIterator<Key, T, Iterator>::operator*() const
|
||||
/*! \fn template<typename Key, typename T, class Iterator> std::pair<Key, T> QKeyValueIterator<Key, T, Iterator>::operator*() const
|
||||
|
||||
Returns the current entry as a pair.
|
||||
*/
|
||||
|
||||
/*! \fn template<typename Key, typename T, class Iterator> pointer QKeyValueIterator<Key, T, Iterator>::operator->() const
|
||||
|
||||
Returns the current entry as a pointer-like object to the pair.
|
||||
|
||||
\since 5.15
|
||||
|
||||
\sa operator*()
|
||||
*/
|
||||
|
||||
/*! \fn template<typename Key, typename T, class Iterator> bool operator==(QKeyValueIterator<Key, T, Iterator> lhs, QKeyValueIterator<Key, T, Iterator> rhs)
|
||||
\relates QKeyValueIterator
|
||||
|
||||
|
@ -814,11 +814,10 @@ void QMapDataBase::freeData(QMapDataBase *d)
|
||||
*/
|
||||
|
||||
/*! \fn template <class Key, class T> int QMap<Key, T>::count(const Key &key) const
|
||||
\obsolete
|
||||
|
||||
Returns the number of items associated with key \a key.
|
||||
|
||||
\sa QMultiMap::count()
|
||||
\sa contains(), QMultiMap::count()
|
||||
*/
|
||||
|
||||
/*! \fn template <class Key, class T> int QMap<Key, T>::count() const
|
||||
@ -2115,11 +2114,6 @@ void QMapDataBase::freeData(QMapDataBase *d)
|
||||
inserted one.
|
||||
*/
|
||||
|
||||
/*! \fn template <class Key, class T> int QMultiMap<Key, T>::count(const Key &key) const
|
||||
|
||||
Returns the number of items associated with key \a key.
|
||||
*/
|
||||
|
||||
/*! \fn template <class Key, class T> QList<Key> QMultiMap<Key, T>::uniqueKeys() const
|
||||
\since 4.2
|
||||
|
||||
|
@ -373,10 +373,10 @@ public:
|
||||
QList<Key> keys(const T &value) const;
|
||||
QList<T> values() const;
|
||||
#if QT_DEPRECATED_SINCE(5, 15)
|
||||
QT_DEPRECATED_X("Use QMultiMap for maps storing multiple values with the same key.") QList<Key> uniqueKeys() const;
|
||||
QT_DEPRECATED_X("Use QMultiMap for maps storing multiple values with the same key.") QList<T> values(const Key &key) const;
|
||||
QT_DEPRECATED_X("Use QMultiMap for maps storing multiple values with the same key.") int count(const Key &key) const;
|
||||
QT_DEPRECATED_VERSION_X_5_15("Use QMultiMap for maps storing multiple values with the same key.") QList<Key> uniqueKeys() const;
|
||||
QT_DEPRECATED_VERSION_X_5_15("Use QMultiMap for maps storing multiple values with the same key.") QList<T> values(const Key &key) const;
|
||||
#endif
|
||||
int count(const Key &key) const;
|
||||
|
||||
|
||||
inline const Key &firstKey() const { Q_ASSERT(!isEmpty()); return constBegin().key(); }
|
||||
@ -559,9 +559,9 @@ public:
|
||||
iterator insert(const_iterator pos, const Key &key, const T &value);
|
||||
void insert(const QMap<Key, T> &map);
|
||||
#if QT_DEPRECATED_SINCE(5, 15)
|
||||
QT_DEPRECATED_X("Use QMultiMap for maps storing multiple values with the same key.") iterator insertMulti(const Key &key, const T &value);
|
||||
QT_DEPRECATED_X("Use QMultiMap for maps storing multiple values with the same key.") iterator insertMulti(const_iterator pos, const Key &akey, const T &avalue);
|
||||
QT_DEPRECATED_X("Use QMultiMap for maps storing multiple values with the same key.") QMap<Key, T> &unite(const QMap<Key, T> &other);
|
||||
QT_DEPRECATED_VERSION_X_5_15("Use QMultiMap for maps storing multiple values with the same key.") iterator insertMulti(const Key &key, const T &value);
|
||||
QT_DEPRECATED_VERSION_X_5_15("Use QMultiMap for maps storing multiple values with the same key.") iterator insertMulti(const_iterator pos, const Key &akey, const T &avalue);
|
||||
QT_DEPRECATED_VERSION_X_5_15("Use QMultiMap for maps storing multiple values with the same key.") QMap<Key, T> &unite(const QMap<Key, T> &other);
|
||||
#endif
|
||||
|
||||
// STL compatibility
|
||||
@ -654,6 +654,23 @@ Q_INLINE_TEMPLATE T &QMap<Key, T>::operator[](const Key &akey)
|
||||
return n->value;
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
Q_INLINE_TEMPLATE int QMap<Key, T>::count(const Key &akey) const
|
||||
{
|
||||
Node *firstNode;
|
||||
Node *lastNode;
|
||||
d->nodeRange(akey, &firstNode, &lastNode);
|
||||
|
||||
const_iterator ci_first(firstNode);
|
||||
const const_iterator ci_last(lastNode);
|
||||
int cnt = 0;
|
||||
while (ci_first != ci_last) {
|
||||
++cnt;
|
||||
++ci_first;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
Q_INLINE_TEMPLATE bool QMap<Key, T>::contains(const Key &akey) const
|
||||
{
|
||||
@ -1116,7 +1133,6 @@ public:
|
||||
|
||||
int remove(const Key &key, const T &value);
|
||||
|
||||
int count(const Key &key) const;
|
||||
int count(const Key &key, const T &value) const;
|
||||
|
||||
typename QMap<Key, T>::iterator find(const Key &key, const T &value) {
|
||||
@ -1289,23 +1305,6 @@ Q_INLINE_TEMPLATE int QMultiMap<Key, T>::remove(const Key &key, const T &value)
|
||||
return n;
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
Q_INLINE_TEMPLATE int QMultiMap<Key, T>::count(const Key &akey) const
|
||||
{
|
||||
QMultiMap::Node *firstNode;
|
||||
QMultiMap::Node *lastNode;
|
||||
this->d->nodeRange(akey, &firstNode, &lastNode);
|
||||
|
||||
typename QMap<Key, T>::const_iterator ci_first(firstNode);
|
||||
const typename QMap<Key, T>::const_iterator ci_last(lastNode);
|
||||
int cnt = 0;
|
||||
while (ci_first != ci_last) {
|
||||
++cnt;
|
||||
++ci_first;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
Q_INLINE_TEMPLATE int QMultiMap<Key, T>::count(const Key &key, const T &value) const
|
||||
{
|
||||
@ -1333,12 +1332,6 @@ QList<T> QMap<Key, T>::values(const Key &key) const
|
||||
return static_cast<const QMultiMap<Key, T> *>(this)->values(key);
|
||||
}
|
||||
|
||||
template<class Key, class T>
|
||||
int QMap<Key, T>::count(const Key &key) const
|
||||
{
|
||||
return static_cast<const QMultiMap<Key, T> *>(this)->count(key);
|
||||
}
|
||||
|
||||
template<class Key, class T>
|
||||
typename QMap<Key, T>::iterator QMap<Key, T>::insertMulti(const Key &key, const T &value)
|
||||
{
|
||||
|
@ -870,13 +870,6 @@ void QBmpHandler::setOption(ImageOption option, const QVariant &value)
|
||||
Q_UNUSED(value);
|
||||
}
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5, 13)
|
||||
QByteArray QBmpHandler::name() const
|
||||
{
|
||||
return formatName();
|
||||
}
|
||||
#endif
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_NO_IMAGEFORMAT_BMP
|
||||
|
@ -113,9 +113,6 @@ public:
|
||||
bool read(QImage *image) override;
|
||||
bool write(const QImage &image) override;
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5, 13)
|
||||
QByteArray name() const override;
|
||||
#endif
|
||||
static bool canRead(QIODevice *device);
|
||||
|
||||
QVariant option(ImageOption option) const override;
|
||||
|
@ -1296,13 +1296,6 @@ void QPngHandler::setOption(ImageOption option, const QVariant &value)
|
||||
d->scaledSize = value.toSize();
|
||||
}
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5, 13)
|
||||
QByteArray QPngHandler::name() const
|
||||
{
|
||||
return "png";
|
||||
}
|
||||
#endif
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_NO_IMAGEFORMAT_PNG
|
||||
|
@ -69,10 +69,6 @@ public:
|
||||
bool read(QImage *image) override;
|
||||
bool write(const QImage &image) override;
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5, 13)
|
||||
QByteArray name() const override;
|
||||
#endif
|
||||
|
||||
QVariant option(ImageOption option) const override;
|
||||
void setOption(ImageOption option, const QVariant &value) override;
|
||||
bool supportsOption(ImageOption option) const override;
|
||||
|
@ -576,13 +576,6 @@ void QPpmHandler::setOption(ImageOption option, const QVariant &value)
|
||||
subType = value.toByteArray().toLower();
|
||||
}
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5, 13)
|
||||
QByteArray QPpmHandler::name() const
|
||||
{
|
||||
return subType.isEmpty() ? QByteArray("ppm") : subType;
|
||||
}
|
||||
#endif
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_NO_IMAGEFORMAT_PPM
|
||||
|
@ -67,10 +67,6 @@ public:
|
||||
bool read(QImage *image) override;
|
||||
bool write(const QImage &image) override;
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5, 13)
|
||||
QByteArray name() const override;
|
||||
#endif
|
||||
|
||||
static bool canRead(QIODevice *device, QByteArray *subType = nullptr);
|
||||
|
||||
QVariant option(ImageOption option) const override;
|
||||
|
@ -357,13 +357,6 @@ void QXbmHandler::setOption(ImageOption option, const QVariant &value)
|
||||
fileName = value.toString();
|
||||
}
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5, 13)
|
||||
QByteArray QXbmHandler::name() const
|
||||
{
|
||||
return "xbm";
|
||||
}
|
||||
#endif
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_NO_IMAGEFORMAT_XBM
|
||||
|
@ -66,10 +66,6 @@ public:
|
||||
bool read(QImage *image) override;
|
||||
bool write(const QImage &image) override;
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5, 13)
|
||||
QByteArray name() const override;
|
||||
#endif
|
||||
|
||||
static bool canRead(QIODevice *device);
|
||||
|
||||
QVariant option(ImageOption option) const override;
|
||||
|
@ -1280,13 +1280,6 @@ void QXpmHandler::setOption(ImageOption option, const QVariant &value)
|
||||
fileName = value.toString();
|
||||
}
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5, 13)
|
||||
QByteArray QXpmHandler::name() const
|
||||
{
|
||||
return "xpm";
|
||||
}
|
||||
#endif
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_NO_IMAGEFORMAT_XPM
|
||||
|
@ -68,10 +68,6 @@ public:
|
||||
|
||||
static bool canRead(QIODevice *device);
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5, 13)
|
||||
QByteArray name() const override;
|
||||
#endif
|
||||
|
||||
QVariant option(ImageOption option) const override;
|
||||
void setOption(ImageOption option, const QVariant &value) override;
|
||||
bool supportsOption(ImageOption option) const override;
|
||||
|
@ -1731,7 +1731,7 @@ void QWindow::setGeometry(const QRect &rect)
|
||||
if (newScreen && isTopLevel())
|
||||
nativeRect = QHighDpi::toNativePixels(rect, newScreen);
|
||||
else
|
||||
nativeRect = QHighDpi::toNativePixels(rect, this);
|
||||
nativeRect = QHighDpi::toNativeLocalPosition(rect, newScreen);
|
||||
d->platformWindow->setGeometry(nativeRect);
|
||||
} else {
|
||||
d->geometry = rect;
|
||||
@ -1782,8 +1782,12 @@ QScreen *QWindowPrivate::screenForGeometry(const QRect &newGeometry) const
|
||||
QRect QWindow::geometry() const
|
||||
{
|
||||
Q_D(const QWindow);
|
||||
if (d->platformWindow)
|
||||
return QHighDpi::fromNativePixels(d->platformWindow->geometry(), this);
|
||||
if (d->platformWindow) {
|
||||
const auto nativeGeometry = d->platformWindow->geometry();
|
||||
return isTopLevel()
|
||||
? QHighDpi::fromNativePixels(nativeGeometry, this)
|
||||
: QHighDpi::fromNativeLocalPosition(nativeGeometry, this);
|
||||
}
|
||||
return d->geometry;
|
||||
}
|
||||
|
||||
|
@ -298,14 +298,21 @@ QWindowSystemInterfacePrivate::GeometryChangeEvent::GeometryChangeEvent(QWindow
|
||||
, window(window)
|
||||
, newGeometry(newGeometry)
|
||||
{
|
||||
if (const QPlatformWindow *pw = window->handle())
|
||||
requestedGeometry = QHighDpi::fromNativePixels(pw->QPlatformWindow::geometry(), window);
|
||||
if (const QPlatformWindow *pw = window->handle()) {
|
||||
const auto nativeGeometry = pw->QPlatformWindow::geometry();
|
||||
requestedGeometry = window->isTopLevel()
|
||||
? QHighDpi::fromNativePixels(nativeGeometry, window)
|
||||
: QHighDpi::fromNativeLocalPosition(nativeGeometry, window);
|
||||
}
|
||||
}
|
||||
|
||||
QT_DEFINE_QPA_EVENT_HANDLER(void, handleGeometryChange, QWindow *window, const QRect &newRect)
|
||||
{
|
||||
Q_ASSERT(window);
|
||||
QWindowSystemInterfacePrivate::GeometryChangeEvent *e = new QWindowSystemInterfacePrivate::GeometryChangeEvent(window, QHighDpi::fromNativePixels(newRect, window));
|
||||
const auto newRectDi = window->isTopLevel()
|
||||
? QHighDpi::fromNativePixels(newRect, window)
|
||||
: QHighDpi::fromNativeLocalPosition(newRect, window);
|
||||
auto e = new QWindowSystemInterfacePrivate::GeometryChangeEvent(window, newRectDi);
|
||||
if (window->handle()) {
|
||||
// Persist the new geometry so that QWindow::geometry() can be queried in the resize event
|
||||
window->handle()->QPlatformWindow::setGeometry(newRect);
|
||||
|
@ -2048,11 +2048,9 @@ QRhiResource::Type QRhiBuffer::resourceType() const
|
||||
UniformBuffer may not even be backed by a native buffer object at all if
|
||||
uniform buffers are not used or supported by a given backend and graphics
|
||||
API. There are also differences to how data is written to the buffer and
|
||||
the type of backing memory used, and, if host visible memory is involved,
|
||||
when memory writes become available and visible. Therefore, in general it
|
||||
is recommended to limit native buffer object access to vertex and index
|
||||
buffers with types Static or Immutable, because these operate in a
|
||||
relatively uniform manner with all backends.
|
||||
the type of backing memory used. For buffers backed by host visible memory,
|
||||
calling this function guarantees that pending host writes are executed for
|
||||
all the returned native buffers.
|
||||
|
||||
\sa QRhi::currentFrameSlot(), QRhi::FramesInFlight
|
||||
*/
|
||||
@ -2341,6 +2339,31 @@ bool QRhiTexture::buildFrom(QRhiTexture::NativeTexture src)
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
With some graphics APIs, such as Vulkan, integrating custom rendering code
|
||||
that uses the graphics API directly needs special care when it comes to
|
||||
image layouts. This function allows communicating the expected layout the
|
||||
image backing the QRhiTexture is in after the native rendering commands.
|
||||
|
||||
For example, consider rendering into a QRhiTexture's VkImage directly with
|
||||
Vulkan in a code block enclosed by QRhiCommandBuffer::beginExternal() and
|
||||
QRhiCommandBuffer::endExternal(), followed by using the image for texture
|
||||
sampling in a QRhi-based render pass. To avoid potentially incorrect image
|
||||
layout transitions, this function can be used to indicate what the image
|
||||
layout will be once the commands recorded in said code block complete.
|
||||
|
||||
Calling this function makes sense only after
|
||||
QRhiCommandBuffer::endExternal() and before a subsequent
|
||||
QRhiCommandBuffer::beginPass().
|
||||
|
||||
This function has no effect with QRhi backends where the underlying
|
||||
graphics API does not expose a concept of image layouts.
|
||||
*/
|
||||
void QRhiTexture::setNativeLayout(int layout)
|
||||
{
|
||||
Q_UNUSED(layout);
|
||||
}
|
||||
|
||||
/*!
|
||||
\class QRhiSampler
|
||||
\internal
|
||||
|
@ -791,6 +791,7 @@ public:
|
||||
virtual bool build() = 0;
|
||||
virtual NativeTexture nativeTexture();
|
||||
virtual bool buildFrom(NativeTexture src);
|
||||
virtual void setNativeLayout(int layout);
|
||||
|
||||
protected:
|
||||
QRhiTexture(QRhiImplementation *rhi, Format format_, const QSize &pixelSize_,
|
||||
|
@ -580,6 +580,11 @@ void QRhiD3D11::setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline
|
||||
}
|
||||
}
|
||||
|
||||
static const int RBM_SUPPORTED_STAGES = 3;
|
||||
static const int RBM_VERTEX = 0;
|
||||
static const int RBM_FRAGMENT = 1;
|
||||
static const int RBM_COMPUTE = 2;
|
||||
|
||||
void QRhiD3D11::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBindings *srb,
|
||||
int dynamicOffsetCount,
|
||||
const QRhiCommandBuffer::DynamicOffset *dynamicOffsets)
|
||||
@ -608,7 +613,7 @@ void QRhiD3D11::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind
|
||||
{
|
||||
QD3D11Buffer *bufD = QRHI_RES(QD3D11Buffer, b->u.ubuf.buf);
|
||||
if (bufD->m_type == QRhiBuffer::Dynamic)
|
||||
executeBufferHostWritesForCurrentFrame(bufD);
|
||||
executeBufferHostWrites(bufD);
|
||||
|
||||
if (bufD->generation != bd.ubuf.generation || bufD->m_id != bd.ubuf.id) {
|
||||
srbUpdate = true;
|
||||
@ -667,8 +672,17 @@ void QRhiD3D11::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind
|
||||
}
|
||||
}
|
||||
|
||||
if (srbUpdate)
|
||||
updateShaderResourceBindings(srbD);
|
||||
if (srbUpdate) {
|
||||
const QShader::NativeResourceBindingMap *resBindMaps[RBM_SUPPORTED_STAGES];
|
||||
memset(resBindMaps, 0, sizeof(resBindMaps));
|
||||
if (gfxPsD) {
|
||||
resBindMaps[RBM_VERTEX] = &gfxPsD->vs.nativeResourceBindingMap;
|
||||
resBindMaps[RBM_FRAGMENT] = &gfxPsD->fs.nativeResourceBindingMap;
|
||||
} else {
|
||||
resBindMaps[RBM_COMPUTE] = &compPsD->cs.nativeResourceBindingMap;
|
||||
}
|
||||
updateShaderResourceBindings(srbD, resBindMaps);
|
||||
}
|
||||
|
||||
const bool srbChanged = gfxPsD ? (cbD->currentGraphicsSrb != srb) : (cbD->currentComputeSrb != srb);
|
||||
const bool srbRebuilt = cbD->currentSrbGeneration != srbD->generation;
|
||||
@ -725,7 +739,7 @@ void QRhiD3D11::setVertexInput(QRhiCommandBuffer *cb,
|
||||
QD3D11Buffer *bufD = QRHI_RES(QD3D11Buffer, bindings[i].first);
|
||||
Q_ASSERT(bufD->m_usage.testFlag(QRhiBuffer::VertexBuffer));
|
||||
if (bufD->m_type == QRhiBuffer::Dynamic)
|
||||
executeBufferHostWritesForCurrentFrame(bufD);
|
||||
executeBufferHostWrites(bufD);
|
||||
|
||||
if (cbD->currentVertexBuffers[inputSlot] != bufD->buffer
|
||||
|| cbD->currentVertexOffsets[inputSlot] != bindings[i].second)
|
||||
@ -757,7 +771,7 @@ void QRhiD3D11::setVertexInput(QRhiCommandBuffer *cb,
|
||||
QD3D11Buffer *ibufD = QRHI_RES(QD3D11Buffer, indexBuf);
|
||||
Q_ASSERT(ibufD->m_usage.testFlag(QRhiBuffer::IndexBuffer));
|
||||
if (ibufD->m_type == QRhiBuffer::Dynamic)
|
||||
executeBufferHostWritesForCurrentFrame(ibufD);
|
||||
executeBufferHostWrites(ibufD);
|
||||
|
||||
const DXGI_FORMAT dxgiFormat = indexFormat == QRhiCommandBuffer::IndexUInt16 ? DXGI_FORMAT_R16_UINT
|
||||
: DXGI_FORMAT_R32_UINT;
|
||||
@ -1774,7 +1788,26 @@ void QRhiD3D11::dispatch(QRhiCommandBuffer *cb, int x, int y, int z)
|
||||
cbD->commands.append(cmd);
|
||||
}
|
||||
|
||||
void QRhiD3D11::updateShaderResourceBindings(QD3D11ShaderResourceBindings *srbD)
|
||||
static inline QPair<int, int> mapBinding(int binding,
|
||||
int stageIndex,
|
||||
const QShader::NativeResourceBindingMap *nativeResourceBindingMaps[])
|
||||
{
|
||||
const QShader::NativeResourceBindingMap *map = nativeResourceBindingMaps[stageIndex];
|
||||
if (!map || map->isEmpty())
|
||||
return { binding, binding }; // old QShader versions do not have this map, assume 1:1 mapping then
|
||||
|
||||
auto it = map->constFind(binding);
|
||||
if (it != map->cend())
|
||||
return *it;
|
||||
|
||||
// Hitting this path is normal too. It is not given that the resource is
|
||||
// present in the shaders for all the stages specified by the visibility
|
||||
// mask in the QRhiShaderResourceBinding.
|
||||
return { -1, -1 };
|
||||
}
|
||||
|
||||
void QRhiD3D11::updateShaderResourceBindings(QD3D11ShaderResourceBindings *srbD,
|
||||
const QShader::NativeResourceBindingMap *nativeResourceBindingMaps[])
|
||||
{
|
||||
srbD->vsubufs.clear();
|
||||
srbD->vsubufoffsets.clear();
|
||||
@ -1799,6 +1832,31 @@ void QRhiD3D11::updateShaderResourceBindings(QD3D11ShaderResourceBindings *srbD)
|
||||
|
||||
srbD->csUAVs.clear();
|
||||
|
||||
struct Stage {
|
||||
struct Buffer {
|
||||
int breg; // b0, b1, ...
|
||||
ID3D11Buffer *buffer;
|
||||
uint offsetInConstants;
|
||||
uint sizeInConstants;
|
||||
};
|
||||
struct Texture {
|
||||
int treg; // t0, t1, ...
|
||||
ID3D11ShaderResourceView *srv;
|
||||
};
|
||||
struct Sampler {
|
||||
int sreg; // s0, s1, ...
|
||||
ID3D11SamplerState *sampler;
|
||||
};
|
||||
struct Uav {
|
||||
int ureg;
|
||||
ID3D11UnorderedAccessView *uav;
|
||||
};
|
||||
QVarLengthArray<Buffer, 8> buffers;
|
||||
QVarLengthArray<Texture, 8> textures;
|
||||
QVarLengthArray<Sampler, 8> samplers;
|
||||
QVarLengthArray<Uav, 8> uavs;
|
||||
} res[RBM_SUPPORTED_STAGES];
|
||||
|
||||
for (int i = 0, ie = srbD->sortedBindings.count(); i != ie; ++i) {
|
||||
const QRhiShaderResourceBinding::Data *b = srbD->sortedBindings.at(i).data();
|
||||
QD3D11ShaderResourceBindings::BoundResourceData &bd(srbD->boundResourceData[i]);
|
||||
@ -1818,26 +1876,24 @@ void QRhiD3D11::updateShaderResourceBindings(QD3D11ShaderResourceBindings *srbD)
|
||||
// (ByteWidth) is always a multiple of 256.
|
||||
const uint sizeInConstants = uint(aligned(b->u.ubuf.maybeSize ? b->u.ubuf.maybeSize : bufD->m_size, 256) / 16);
|
||||
if (b->stage.testFlag(QRhiShaderResourceBinding::VertexStage)) {
|
||||
srbD->vsubufs.feed(b->binding, bufD->buffer);
|
||||
srbD->vsubufoffsets.feed(b->binding, offsetInConstants);
|
||||
srbD->vsubufsizes.feed(b->binding, sizeInConstants);
|
||||
QPair<int, int> nativeBinding = mapBinding(b->binding, RBM_VERTEX, nativeResourceBindingMaps);
|
||||
if (nativeBinding.first >= 0)
|
||||
res[RBM_VERTEX].buffers.append({ nativeBinding.first, bufD->buffer, offsetInConstants, sizeInConstants });
|
||||
}
|
||||
if (b->stage.testFlag(QRhiShaderResourceBinding::FragmentStage)) {
|
||||
srbD->fsubufs.feed(b->binding, bufD->buffer);
|
||||
srbD->fsubufoffsets.feed(b->binding, offsetInConstants);
|
||||
srbD->fsubufsizes.feed(b->binding, sizeInConstants);
|
||||
QPair<int, int> nativeBinding = mapBinding(b->binding, RBM_FRAGMENT, nativeResourceBindingMaps);
|
||||
if (nativeBinding.first >= 0)
|
||||
res[RBM_FRAGMENT].buffers.append({ nativeBinding.first, bufD->buffer, offsetInConstants, sizeInConstants });
|
||||
}
|
||||
if (b->stage.testFlag(QRhiShaderResourceBinding::ComputeStage)) {
|
||||
srbD->csubufs.feed(b->binding, bufD->buffer);
|
||||
srbD->csubufoffsets.feed(b->binding, offsetInConstants);
|
||||
srbD->csubufsizes.feed(b->binding, sizeInConstants);
|
||||
QPair<int, int> nativeBinding = mapBinding(b->binding, RBM_COMPUTE, nativeResourceBindingMaps);
|
||||
if (nativeBinding.first >= 0)
|
||||
res[RBM_COMPUTE].buffers.append({ nativeBinding.first, bufD->buffer, offsetInConstants, sizeInConstants });
|
||||
}
|
||||
}
|
||||
break;
|
||||
case QRhiShaderResourceBinding::SampledTexture:
|
||||
{
|
||||
// A sampler with binding N is mapped to a HLSL sampler and texture
|
||||
// with registers sN and tN by SPIRV-Cross.
|
||||
QD3D11Texture *texD = QRHI_RES(QD3D11Texture, b->u.stex.tex);
|
||||
QD3D11Sampler *samplerD = QRHI_RES(QD3D11Sampler, b->u.stex.sampler);
|
||||
bd.stex.texId = texD->m_id;
|
||||
@ -1845,16 +1901,25 @@ void QRhiD3D11::updateShaderResourceBindings(QD3D11ShaderResourceBindings *srbD)
|
||||
bd.stex.samplerId = samplerD->m_id;
|
||||
bd.stex.samplerGeneration = samplerD->generation;
|
||||
if (b->stage.testFlag(QRhiShaderResourceBinding::VertexStage)) {
|
||||
srbD->vssamplers.feed(b->binding, samplerD->samplerState);
|
||||
srbD->vsshaderresources.feed(b->binding, texD->srv);
|
||||
QPair<int, int> nativeBinding = mapBinding(b->binding, RBM_VERTEX, nativeResourceBindingMaps);
|
||||
if (nativeBinding.first >= 0 && nativeBinding.second >= 0) {
|
||||
res[RBM_VERTEX].textures.append({ nativeBinding.first, texD->srv });
|
||||
res[RBM_VERTEX].samplers.append({ nativeBinding.second, samplerD->samplerState });
|
||||
}
|
||||
}
|
||||
if (b->stage.testFlag(QRhiShaderResourceBinding::FragmentStage)) {
|
||||
srbD->fssamplers.feed(b->binding, samplerD->samplerState);
|
||||
srbD->fsshaderresources.feed(b->binding, texD->srv);
|
||||
QPair<int, int> nativeBinding = mapBinding(b->binding, RBM_FRAGMENT, nativeResourceBindingMaps);
|
||||
if (nativeBinding.first >= 0 && nativeBinding.second >= 0) {
|
||||
res[RBM_FRAGMENT].textures.append({ nativeBinding.first, texD->srv });
|
||||
res[RBM_FRAGMENT].samplers.append({ nativeBinding.second, samplerD->samplerState });
|
||||
}
|
||||
}
|
||||
if (b->stage.testFlag(QRhiShaderResourceBinding::ComputeStage)) {
|
||||
srbD->cssamplers.feed(b->binding, samplerD->samplerState);
|
||||
srbD->csshaderresources.feed(b->binding, texD->srv);
|
||||
QPair<int, int> nativeBinding = mapBinding(b->binding, RBM_COMPUTE, nativeResourceBindingMaps);
|
||||
if (nativeBinding.first >= 0 && nativeBinding.second >= 0) {
|
||||
res[RBM_COMPUTE].textures.append({ nativeBinding.first, texD->srv });
|
||||
res[RBM_COMPUTE].samplers.append({ nativeBinding.second, samplerD->samplerState });
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1866,9 +1931,12 @@ void QRhiD3D11::updateShaderResourceBindings(QD3D11ShaderResourceBindings *srbD)
|
||||
bd.simage.id = texD->m_id;
|
||||
bd.simage.generation = texD->generation;
|
||||
if (b->stage.testFlag(QRhiShaderResourceBinding::ComputeStage)) {
|
||||
ID3D11UnorderedAccessView *uav = texD->unorderedAccessViewForLevel(b->u.simage.level);
|
||||
if (uav)
|
||||
srbD->csUAVs.feed(b->binding, uav);
|
||||
QPair<int, int> nativeBinding = mapBinding(b->binding, RBM_COMPUTE, nativeResourceBindingMaps);
|
||||
if (nativeBinding.first >= 0) {
|
||||
ID3D11UnorderedAccessView *uav = texD->unorderedAccessViewForLevel(b->u.simage.level);
|
||||
if (uav)
|
||||
res[RBM_COMPUTE].uavs.append({ nativeBinding.first, uav });
|
||||
}
|
||||
} else {
|
||||
qWarning("Unordered access only supported at compute stage");
|
||||
}
|
||||
@ -1882,9 +1950,12 @@ void QRhiD3D11::updateShaderResourceBindings(QD3D11ShaderResourceBindings *srbD)
|
||||
bd.sbuf.id = bufD->m_id;
|
||||
bd.sbuf.generation = bufD->generation;
|
||||
if (b->stage.testFlag(QRhiShaderResourceBinding::ComputeStage)) {
|
||||
ID3D11UnorderedAccessView *uav = bufD->unorderedAccessView();
|
||||
if (uav)
|
||||
srbD->csUAVs.feed(b->binding, uav);
|
||||
QPair<int, int> nativeBinding = mapBinding(b->binding, RBM_COMPUTE, nativeResourceBindingMaps);
|
||||
if (nativeBinding.first >= 0) {
|
||||
ID3D11UnorderedAccessView *uav = bufD->unorderedAccessView();
|
||||
if (uav)
|
||||
res[RBM_COMPUTE].uavs.append({ nativeBinding.first, uav });
|
||||
}
|
||||
} else {
|
||||
qWarning("Unordered access only supported at compute stage");
|
||||
}
|
||||
@ -1896,31 +1967,79 @@ void QRhiD3D11::updateShaderResourceBindings(QD3D11ShaderResourceBindings *srbD)
|
||||
}
|
||||
}
|
||||
|
||||
// QRhiBatchedBindings works with the native bindings and expects
|
||||
// sorted input. The pre-sorted QRhiShaderResourceBinding list (based
|
||||
// on the QRhi (SPIR-V) binding) is not helpful in this regard, so we
|
||||
// have to sort here every time.
|
||||
for (int stage = 0; stage < RBM_SUPPORTED_STAGES; ++stage) {
|
||||
std::sort(res[stage].buffers.begin(), res[stage].buffers.end(), [](const Stage::Buffer &a, const Stage::Buffer &b) {
|
||||
return a.breg < b.breg;
|
||||
});
|
||||
std::sort(res[stage].textures.begin(), res[stage].textures.end(), [](const Stage::Texture &a, const Stage::Texture &b) {
|
||||
return a.treg < b.treg;
|
||||
});
|
||||
std::sort(res[stage].samplers.begin(), res[stage].samplers.end(), [](const Stage::Sampler &a, const Stage::Sampler &b) {
|
||||
return a.sreg < b.sreg;
|
||||
});
|
||||
std::sort(res[stage].uavs.begin(), res[stage].uavs.end(), [](const Stage::Uav &a, const Stage::Uav &b) {
|
||||
return a.ureg < b.ureg;
|
||||
});
|
||||
}
|
||||
|
||||
for (const Stage::Buffer &buf : qAsConst(res[RBM_VERTEX].buffers)) {
|
||||
srbD->vsubufs.feed(buf.breg, buf.buffer);
|
||||
srbD->vsubufoffsets.feed(buf.breg, buf.offsetInConstants);
|
||||
srbD->vsubufsizes.feed(buf.breg, buf.sizeInConstants);
|
||||
}
|
||||
srbD->vsubufs.finish();
|
||||
srbD->vsubufoffsets.finish();
|
||||
srbD->vsubufsizes.finish();
|
||||
|
||||
for (const Stage::Buffer &buf : qAsConst(res[RBM_FRAGMENT].buffers)) {
|
||||
srbD->fsubufs.feed(buf.breg, buf.buffer);
|
||||
srbD->fsubufoffsets.feed(buf.breg, buf.offsetInConstants);
|
||||
srbD->fsubufsizes.feed(buf.breg, buf.sizeInConstants);
|
||||
}
|
||||
srbD->fsubufs.finish();
|
||||
srbD->fsubufoffsets.finish();
|
||||
srbD->fsubufsizes.finish();
|
||||
|
||||
for (const Stage::Buffer &buf : qAsConst(res[RBM_COMPUTE].buffers)) {
|
||||
srbD->csubufs.feed(buf.breg, buf.buffer);
|
||||
srbD->csubufoffsets.feed(buf.breg, buf.offsetInConstants);
|
||||
srbD->csubufsizes.feed(buf.breg, buf.sizeInConstants);
|
||||
}
|
||||
srbD->csubufs.finish();
|
||||
srbD->csubufoffsets.finish();
|
||||
srbD->csubufsizes.finish();
|
||||
|
||||
for (const Stage::Texture &t : qAsConst(res[RBM_VERTEX].textures))
|
||||
srbD->vsshaderresources.feed(t.treg, t.srv);
|
||||
for (const Stage::Sampler &s : qAsConst(res[RBM_VERTEX].samplers))
|
||||
srbD->vssamplers.feed(s.sreg, s.sampler);
|
||||
srbD->vssamplers.finish();
|
||||
srbD->vsshaderresources.finish();
|
||||
|
||||
for (const Stage::Texture &t : qAsConst(res[RBM_FRAGMENT].textures))
|
||||
srbD->fsshaderresources.feed(t.treg, t.srv);
|
||||
for (const Stage::Sampler &s : qAsConst(res[RBM_FRAGMENT].samplers))
|
||||
srbD->fssamplers.feed(s.sreg, s.sampler);
|
||||
srbD->fssamplers.finish();
|
||||
srbD->fsshaderresources.finish();
|
||||
|
||||
for (const Stage::Texture &t : qAsConst(res[RBM_COMPUTE].textures))
|
||||
srbD->csshaderresources.feed(t.treg, t.srv);
|
||||
for (const Stage::Sampler &s : qAsConst(res[RBM_COMPUTE].samplers))
|
||||
srbD->cssamplers.feed(s.sreg, s.sampler);
|
||||
srbD->cssamplers.finish();
|
||||
srbD->csshaderresources.finish();
|
||||
|
||||
for (const Stage::Uav &u : qAsConst(res[RBM_COMPUTE].uavs))
|
||||
srbD->csUAVs.feed(u.ureg, u.uav);
|
||||
srbD->csUAVs.finish();
|
||||
}
|
||||
|
||||
void QRhiD3D11::executeBufferHostWritesForCurrentFrame(QD3D11Buffer *bufD)
|
||||
void QRhiD3D11::executeBufferHostWrites(QD3D11Buffer *bufD)
|
||||
{
|
||||
if (!bufD->hasPendingDynamicUpdates)
|
||||
return;
|
||||
@ -2205,8 +2324,8 @@ void QRhiD3D11::executeCommandBuffer(QD3D11CommandBuffer *cbD, QD3D11SwapChain *
|
||||
case QD3D11CommandBuffer::Command::BindGraphicsPipeline:
|
||||
{
|
||||
QD3D11GraphicsPipeline *psD = cmd.args.bindGraphicsPipeline.ps;
|
||||
context->VSSetShader(psD->vs, nullptr, 0);
|
||||
context->PSSetShader(psD->fs, nullptr, 0);
|
||||
context->VSSetShader(psD->vs.shader, nullptr, 0);
|
||||
context->PSSetShader(psD->fs.shader, nullptr, 0);
|
||||
context->IASetPrimitiveTopology(psD->d3dTopology);
|
||||
context->IASetInputLayout(psD->inputLayout);
|
||||
context->OMSetDepthStencilState(psD->dsState, stencilRef);
|
||||
@ -2281,7 +2400,7 @@ void QRhiD3D11::executeCommandBuffer(QD3D11CommandBuffer *cbD, QD3D11SwapChain *
|
||||
annotations->SetMarker(reinterpret_cast<LPCWSTR>(QString::fromLatin1(cmd.args.debugMark.s).utf16()));
|
||||
break;
|
||||
case QD3D11CommandBuffer::Command::BindComputePipeline:
|
||||
context->CSSetShader(cmd.args.bindComputePipeline.ps->cs, nullptr, 0);
|
||||
context->CSSetShader(cmd.args.bindComputePipeline.ps->cs.shader, nullptr, 0);
|
||||
break;
|
||||
case QD3D11CommandBuffer::Command::Dispatch:
|
||||
context->Dispatch(cmd.args.dispatch.x, cmd.args.dispatch.y, cmd.args.dispatch.z);
|
||||
@ -2388,6 +2507,10 @@ bool QD3D11Buffer::build()
|
||||
|
||||
QRhiBuffer::NativeBuffer QD3D11Buffer::nativeBuffer()
|
||||
{
|
||||
if (m_type == Dynamic) {
|
||||
QRHI_RES_RHI(QRhiD3D11);
|
||||
rhiD->executeBufferHostWrites(this);
|
||||
}
|
||||
return { { &buffer }, 1 };
|
||||
}
|
||||
|
||||
@ -3133,6 +3256,7 @@ QD3D11ShaderResourceBindings::~QD3D11ShaderResourceBindings()
|
||||
void QD3D11ShaderResourceBindings::release()
|
||||
{
|
||||
sortedBindings.clear();
|
||||
boundResourceData.clear();
|
||||
}
|
||||
|
||||
bool QD3D11ShaderResourceBindings::build()
|
||||
@ -3149,8 +3273,8 @@ bool QD3D11ShaderResourceBindings::build()
|
||||
|
||||
boundResourceData.resize(sortedBindings.count());
|
||||
|
||||
QRHI_RES_RHI(QRhiD3D11);
|
||||
rhiD->updateShaderResourceBindings(this);
|
||||
for (BoundResourceData &bd : boundResourceData)
|
||||
memset(&bd, 0, sizeof(BoundResourceData));
|
||||
|
||||
generation += 1;
|
||||
return true;
|
||||
@ -3191,15 +3315,17 @@ void QD3D11GraphicsPipeline::release()
|
||||
rastState = nullptr;
|
||||
}
|
||||
|
||||
if (vs) {
|
||||
vs->Release();
|
||||
vs = nullptr;
|
||||
if (vs.shader) {
|
||||
vs.shader->Release();
|
||||
vs.shader = nullptr;
|
||||
}
|
||||
vs.nativeResourceBindingMap.clear();
|
||||
|
||||
if (fs) {
|
||||
fs->Release();
|
||||
fs = nullptr;
|
||||
if (fs.shader) {
|
||||
fs.shader->Release();
|
||||
fs.shader = nullptr;
|
||||
}
|
||||
fs.nativeResourceBindingMap.clear();
|
||||
|
||||
rhiD->unregisterResource(this);
|
||||
}
|
||||
@ -3401,13 +3527,14 @@ static pD3DCompile resolveD3DCompile()
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static QByteArray compileHlslShaderSource(const QShader &shader, QShader::Variant shaderVariant, QString *error)
|
||||
static QByteArray compileHlslShaderSource(const QShader &shader, QShader::Variant shaderVariant, QString *error, QShaderKey *usedShaderKey)
|
||||
{
|
||||
QShaderCode dxbc = shader.shader({ QShader::DxbcShader, 50, shaderVariant });
|
||||
if (!dxbc.shader().isEmpty())
|
||||
return dxbc.shader();
|
||||
|
||||
QShaderCode hlslSource = shader.shader({ QShader::HlslShader, 50, shaderVariant });
|
||||
const QShaderKey key = { QShader::HlslShader, 50, shaderVariant };
|
||||
QShaderCode hlslSource = shader.shader(key);
|
||||
if (hlslSource.shader().isEmpty()) {
|
||||
qWarning() << "No HLSL (shader model 5.0) code found in baked shader" << shader;
|
||||
return QByteArray();
|
||||
@ -3459,6 +3586,9 @@ static QByteArray compileHlslShaderSource(const QShader &shader, QShader::Varian
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
if (usedShaderKey)
|
||||
*usedShaderKey = key;
|
||||
|
||||
QByteArray result;
|
||||
result.resize(int(bytecode->GetBufferSize()));
|
||||
memcpy(result.data(), bytecode->GetBufferPointer(), size_t(result.size()));
|
||||
@ -3550,20 +3680,23 @@ bool QD3D11GraphicsPipeline::build()
|
||||
if (cacheIt != rhiD->m_shaderCache.constEnd()) {
|
||||
switch (shaderStage.type()) {
|
||||
case QRhiShaderStage::Vertex:
|
||||
vs = static_cast<ID3D11VertexShader *>(cacheIt->s);
|
||||
vs->AddRef();
|
||||
vs.shader = static_cast<ID3D11VertexShader *>(cacheIt->s);
|
||||
vs.shader->AddRef();
|
||||
vsByteCode = cacheIt->bytecode;
|
||||
vs.nativeResourceBindingMap = cacheIt->nativeResourceBindingMap;
|
||||
break;
|
||||
case QRhiShaderStage::Fragment:
|
||||
fs = static_cast<ID3D11PixelShader *>(cacheIt->s);
|
||||
fs->AddRef();
|
||||
fs.shader = static_cast<ID3D11PixelShader *>(cacheIt->s);
|
||||
fs.shader->AddRef();
|
||||
fs.nativeResourceBindingMap = cacheIt->nativeResourceBindingMap;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
QString error;
|
||||
const QByteArray bytecode = compileHlslShaderSource(shaderStage.shader(), shaderStage.shaderVariant(), &error);
|
||||
QShaderKey shaderKey;
|
||||
const QByteArray bytecode = compileHlslShaderSource(shaderStage.shader(), shaderStage.shaderVariant(), &error, &shaderKey);
|
||||
if (bytecode.isEmpty()) {
|
||||
qWarning("HLSL shader compilation failed: %s", qPrintable(error));
|
||||
return false;
|
||||
@ -3576,23 +3709,27 @@ bool QD3D11GraphicsPipeline::build()
|
||||
|
||||
switch (shaderStage.type()) {
|
||||
case QRhiShaderStage::Vertex:
|
||||
hr = rhiD->dev->CreateVertexShader(bytecode.constData(), SIZE_T(bytecode.size()), nullptr, &vs);
|
||||
hr = rhiD->dev->CreateVertexShader(bytecode.constData(), SIZE_T(bytecode.size()), nullptr, &vs.shader);
|
||||
if (FAILED(hr)) {
|
||||
qWarning("Failed to create vertex shader: %s", qPrintable(comErrorMessage(hr)));
|
||||
return false;
|
||||
}
|
||||
vsByteCode = bytecode;
|
||||
rhiD->m_shaderCache.insert(shaderStage, QRhiD3D11::Shader(vs, bytecode));
|
||||
vs->AddRef();
|
||||
if (const QShader::NativeResourceBindingMap *map = shaderStage.shader().nativeResourceBindingMap(shaderKey))
|
||||
vs.nativeResourceBindingMap = *map;
|
||||
rhiD->m_shaderCache.insert(shaderStage, QRhiD3D11::Shader(vs.shader, bytecode, vs.nativeResourceBindingMap));
|
||||
vs.shader->AddRef();
|
||||
break;
|
||||
case QRhiShaderStage::Fragment:
|
||||
hr = rhiD->dev->CreatePixelShader(bytecode.constData(), SIZE_T(bytecode.size()), nullptr, &fs);
|
||||
hr = rhiD->dev->CreatePixelShader(bytecode.constData(), SIZE_T(bytecode.size()), nullptr, &fs.shader);
|
||||
if (FAILED(hr)) {
|
||||
qWarning("Failed to create pixel shader: %s", qPrintable(comErrorMessage(hr)));
|
||||
return false;
|
||||
}
|
||||
rhiD->m_shaderCache.insert(shaderStage, QRhiD3D11::Shader(fs, bytecode));
|
||||
fs->AddRef();
|
||||
if (const QShader::NativeResourceBindingMap *map = shaderStage.shader().nativeResourceBindingMap(shaderKey))
|
||||
fs.nativeResourceBindingMap = *map;
|
||||
rhiD->m_shaderCache.insert(shaderStage, QRhiD3D11::Shader(fs.shader, bytecode, fs.nativeResourceBindingMap));
|
||||
fs.shader->AddRef();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -3651,46 +3788,52 @@ void QD3D11ComputePipeline::release()
|
||||
{
|
||||
QRHI_RES_RHI(QRhiD3D11);
|
||||
|
||||
if (!cs)
|
||||
if (!cs.shader)
|
||||
return;
|
||||
|
||||
cs->Release();
|
||||
cs = nullptr;
|
||||
cs.shader->Release();
|
||||
cs.shader = nullptr;
|
||||
cs.nativeResourceBindingMap.clear();
|
||||
|
||||
rhiD->unregisterResource(this);
|
||||
}
|
||||
|
||||
bool QD3D11ComputePipeline::build()
|
||||
{
|
||||
if (cs)
|
||||
if (cs.shader)
|
||||
release();
|
||||
|
||||
QRHI_RES_RHI(QRhiD3D11);
|
||||
|
||||
auto cacheIt = rhiD->m_shaderCache.constFind(m_shaderStage);
|
||||
if (cacheIt != rhiD->m_shaderCache.constEnd()) {
|
||||
cs = static_cast<ID3D11ComputeShader *>(cacheIt->s);
|
||||
cs.shader = static_cast<ID3D11ComputeShader *>(cacheIt->s);
|
||||
cs.nativeResourceBindingMap = cacheIt->nativeResourceBindingMap;
|
||||
} else {
|
||||
QString error;
|
||||
const QByteArray bytecode = compileHlslShaderSource(m_shaderStage.shader(), m_shaderStage.shaderVariant(), &error);
|
||||
QShaderKey shaderKey;
|
||||
const QByteArray bytecode = compileHlslShaderSource(m_shaderStage.shader(), m_shaderStage.shaderVariant(), &error, &shaderKey);
|
||||
if (bytecode.isEmpty()) {
|
||||
qWarning("HLSL compute shader compilation failed: %s", qPrintable(error));
|
||||
return false;
|
||||
}
|
||||
|
||||
HRESULT hr = rhiD->dev->CreateComputeShader(bytecode.constData(), SIZE_T(bytecode.size()), nullptr, &cs);
|
||||
HRESULT hr = rhiD->dev->CreateComputeShader(bytecode.constData(), SIZE_T(bytecode.size()), nullptr, &cs.shader);
|
||||
if (FAILED(hr)) {
|
||||
qWarning("Failed to create compute shader: %s", qPrintable(comErrorMessage(hr)));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (const QShader::NativeResourceBindingMap *map = m_shaderStage.shader().nativeResourceBindingMap(shaderKey))
|
||||
cs.nativeResourceBindingMap = *map;
|
||||
|
||||
if (rhiD->m_shaderCache.count() >= QRhiD3D11::MAX_SHADER_CACHE_ENTRIES)
|
||||
rhiD->clearShaderCache();
|
||||
|
||||
rhiD->m_shaderCache.insert(m_shaderStage, QRhiD3D11::Shader(cs, bytecode));
|
||||
rhiD->m_shaderCache.insert(m_shaderStage, QRhiD3D11::Shader(cs.shader, bytecode, cs.nativeResourceBindingMap));
|
||||
}
|
||||
|
||||
cs->AddRef();
|
||||
cs.shader->AddRef();
|
||||
|
||||
generation += 1;
|
||||
rhiD->registerResource(this);
|
||||
|
@ -270,8 +270,14 @@ struct QD3D11GraphicsPipeline : public QRhiGraphicsPipeline
|
||||
|
||||
ID3D11DepthStencilState *dsState = nullptr;
|
||||
ID3D11BlendState *blendState = nullptr;
|
||||
ID3D11VertexShader *vs = nullptr;
|
||||
ID3D11PixelShader *fs = nullptr;
|
||||
struct {
|
||||
ID3D11VertexShader *shader = nullptr;
|
||||
QShader::NativeResourceBindingMap nativeResourceBindingMap;
|
||||
} vs;
|
||||
struct {
|
||||
ID3D11PixelShader *shader = nullptr;
|
||||
QShader::NativeResourceBindingMap nativeResourceBindingMap;
|
||||
} fs;
|
||||
ID3D11InputLayout *inputLayout = nullptr;
|
||||
D3D11_PRIMITIVE_TOPOLOGY d3dTopology = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
|
||||
ID3D11RasterizerState *rastState = nullptr;
|
||||
@ -286,7 +292,10 @@ struct QD3D11ComputePipeline : public QRhiComputePipeline
|
||||
void release() override;
|
||||
bool build() override;
|
||||
|
||||
ID3D11ComputeShader *cs = nullptr;
|
||||
struct {
|
||||
ID3D11ComputeShader *shader = nullptr;
|
||||
QShader::NativeResourceBindingMap nativeResourceBindingMap;
|
||||
} cs;
|
||||
uint generation = 0;
|
||||
friend class QRhiD3D11;
|
||||
};
|
||||
@ -642,8 +651,9 @@ public:
|
||||
void enqueueSubresUpload(QD3D11Texture *texD, QD3D11CommandBuffer *cbD,
|
||||
int layer, int level, const QRhiTextureSubresourceUploadDescription &subresDesc);
|
||||
void enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates);
|
||||
void updateShaderResourceBindings(QD3D11ShaderResourceBindings *srbD);
|
||||
void executeBufferHostWritesForCurrentFrame(QD3D11Buffer *bufD);
|
||||
void updateShaderResourceBindings(QD3D11ShaderResourceBindings *srbD,
|
||||
const QShader::NativeResourceBindingMap *nativeResourceBindingMaps[]);
|
||||
void executeBufferHostWrites(QD3D11Buffer *bufD);
|
||||
void bindShaderResources(QD3D11ShaderResourceBindings *srbD,
|
||||
const uint *dynOfsPairs, int dynOfsPairCount,
|
||||
bool offsetOnlyChange);
|
||||
@ -701,9 +711,11 @@ public:
|
||||
|
||||
struct Shader {
|
||||
Shader() = default;
|
||||
Shader(IUnknown *s, const QByteArray &bytecode) : s(s), bytecode(bytecode) { }
|
||||
Shader(IUnknown *s, const QByteArray &bytecode, const QShader::NativeResourceBindingMap &rbm)
|
||||
: s(s), bytecode(bytecode), nativeResourceBindingMap(rbm) { }
|
||||
IUnknown *s;
|
||||
QByteArray bytecode;
|
||||
QShader::NativeResourceBindingMap nativeResourceBindingMap;
|
||||
};
|
||||
QHash<QRhiShaderStage, Shader> m_shaderCache;
|
||||
|
||||
|
@ -1827,16 +1827,15 @@ void QRhiMetal::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
|
||||
}
|
||||
|
||||
// this handles all types of buffers, not just Dynamic
|
||||
void QRhiMetal::executeBufferHostWritesForCurrentFrame(QMetalBuffer *bufD)
|
||||
void QRhiMetal::executeBufferHostWritesForSlot(QMetalBuffer *bufD, int slot)
|
||||
{
|
||||
const int idx = bufD->d->slotted ? currentFrameSlot : 0;
|
||||
if (bufD->d->pendingUpdates[idx].isEmpty())
|
||||
if (bufD->d->pendingUpdates[slot].isEmpty())
|
||||
return;
|
||||
|
||||
void *p = [bufD->d->buf[idx] contents];
|
||||
void *p = [bufD->d->buf[slot] contents];
|
||||
int changeBegin = -1;
|
||||
int changeEnd = -1;
|
||||
for (const QRhiResourceUpdateBatchPrivate::BufferOp &u : qAsConst(bufD->d->pendingUpdates[idx])) {
|
||||
for (const QRhiResourceUpdateBatchPrivate::BufferOp &u : qAsConst(bufD->d->pendingUpdates[slot])) {
|
||||
Q_ASSERT(bufD == QRHI_RES(QMetalBuffer, u.buf));
|
||||
memcpy(static_cast<char *>(p) + u.offset, u.data.constData(), size_t(u.data.size()));
|
||||
if (changeBegin == -1 || u.offset < changeBegin)
|
||||
@ -1846,10 +1845,15 @@ void QRhiMetal::executeBufferHostWritesForCurrentFrame(QMetalBuffer *bufD)
|
||||
}
|
||||
#ifdef Q_OS_MACOS
|
||||
if (changeBegin >= 0 && bufD->d->managed)
|
||||
[bufD->d->buf[idx] didModifyRange: NSMakeRange(NSUInteger(changeBegin), NSUInteger(changeEnd - changeBegin))];
|
||||
[bufD->d->buf[slot] didModifyRange: NSMakeRange(NSUInteger(changeBegin), NSUInteger(changeEnd - changeBegin))];
|
||||
#endif
|
||||
|
||||
bufD->d->pendingUpdates[idx].clear();
|
||||
bufD->d->pendingUpdates[slot].clear();
|
||||
}
|
||||
|
||||
void QRhiMetal::executeBufferHostWritesForCurrentFrame(QMetalBuffer *bufD)
|
||||
{
|
||||
executeBufferHostWritesForSlot(bufD, bufD->d->slotted ? currentFrameSlot : 0);
|
||||
}
|
||||
|
||||
void QRhiMetal::resourceUpdate(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates)
|
||||
@ -2205,8 +2209,11 @@ QRhiBuffer::NativeBuffer QMetalBuffer::nativeBuffer()
|
||||
if (d->slotted) {
|
||||
NativeBuffer b;
|
||||
Q_ASSERT(sizeof(b.objects) / sizeof(b.objects[0]) >= size_t(QMTL_FRAMES_IN_FLIGHT));
|
||||
for (int i = 0; i < QMTL_FRAMES_IN_FLIGHT; ++i)
|
||||
for (int i = 0; i < QMTL_FRAMES_IN_FLIGHT; ++i) {
|
||||
QRHI_RES_RHI(QRhiMetal);
|
||||
rhiD->executeBufferHostWritesForSlot(this, i);
|
||||
b.objects[i] = &d->buf[i];
|
||||
}
|
||||
b.slotCount = QMTL_FRAMES_IN_FLIGHT;
|
||||
return b;
|
||||
}
|
||||
|
@ -437,6 +437,7 @@ public:
|
||||
int layer, int level, const QRhiTextureSubresourceUploadDescription &subresDesc,
|
||||
qsizetype *curOfs);
|
||||
void enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates);
|
||||
void executeBufferHostWritesForSlot(QMetalBuffer *bufD, int slot);
|
||||
void executeBufferHostWritesForCurrentFrame(QMetalBuffer *bufD);
|
||||
static const int SUPPORTED_STAGES = 3;
|
||||
void enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD,
|
||||
|
@ -149,6 +149,10 @@ QT_BEGIN_NAMESPACE
|
||||
for other windows as well, as long as they all have their
|
||||
QWindow::surfaceType() set to QSurface::VulkanSurface.
|
||||
|
||||
To request additional extensions to be enabled on the Vulkan device, list them
|
||||
in deviceExtensions. This can be relevant when integrating with native Vulkan
|
||||
rendering code.
|
||||
|
||||
\section2 Working with existing Vulkan devices
|
||||
|
||||
When interoperating with another graphics engine, it may be necessary to
|
||||
@ -299,6 +303,7 @@ QRhiVulkan::QRhiVulkan(QRhiVulkanInitParams *params, QRhiVulkanNativeHandles *im
|
||||
{
|
||||
inst = params->inst;
|
||||
maybeWindow = params->window; // may be null
|
||||
requestedDeviceExtensions = params->deviceExtensions;
|
||||
|
||||
importedDevice = importDevice != nullptr;
|
||||
if (importedDevice) {
|
||||
@ -463,40 +468,59 @@ bool QRhiVulkan::create(QRhi::Flags flags)
|
||||
if (inst->layers().contains("VK_LAYER_LUNARG_standard_validation"))
|
||||
devLayers.append("VK_LAYER_LUNARG_standard_validation");
|
||||
|
||||
QVulkanInfoVector<QVulkanExtension> devExts;
|
||||
uint32_t devExtCount = 0;
|
||||
f->vkEnumerateDeviceExtensionProperties(physDev, nullptr, &devExtCount, nullptr);
|
||||
QVector<VkExtensionProperties> devExts(devExtCount);
|
||||
f->vkEnumerateDeviceExtensionProperties(physDev, nullptr, &devExtCount, devExts.data());
|
||||
if (devExtCount) {
|
||||
QVector<VkExtensionProperties> extProps(devExtCount);
|
||||
f->vkEnumerateDeviceExtensionProperties(physDev, nullptr, &devExtCount, extProps.data());
|
||||
for (const VkExtensionProperties &p : qAsConst(extProps))
|
||||
devExts.append({ p.extensionName, p.specVersion });
|
||||
}
|
||||
qCDebug(QRHI_LOG_INFO, "%d device extensions available", devExts.count());
|
||||
|
||||
QVector<const char *> requestedDevExts;
|
||||
requestedDevExts.append("VK_KHR_swapchain");
|
||||
|
||||
debugMarkersAvailable = false;
|
||||
if (devExts.contains(VK_EXT_DEBUG_MARKER_EXTENSION_NAME)) {
|
||||
requestedDevExts.append(VK_EXT_DEBUG_MARKER_EXTENSION_NAME);
|
||||
debugMarkersAvailable = true;
|
||||
}
|
||||
|
||||
vertexAttribDivisorAvailable = false;
|
||||
for (const VkExtensionProperties &ext : devExts) {
|
||||
if (!strcmp(ext.extensionName, VK_EXT_DEBUG_MARKER_EXTENSION_NAME)) {
|
||||
requestedDevExts.append(VK_EXT_DEBUG_MARKER_EXTENSION_NAME);
|
||||
debugMarkersAvailable = true;
|
||||
} else if (!strcmp(ext.extensionName, VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME)) {
|
||||
if (inst->extensions().contains(QByteArrayLiteral("VK_KHR_get_physical_device_properties2"))) {
|
||||
requestedDevExts.append(VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME);
|
||||
vertexAttribDivisorAvailable = true;
|
||||
}
|
||||
if (devExts.contains(VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME)) {
|
||||
if (inst->extensions().contains(QByteArrayLiteral("VK_KHR_get_physical_device_properties2"))) {
|
||||
requestedDevExts.append(VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME);
|
||||
vertexAttribDivisorAvailable = true;
|
||||
}
|
||||
}
|
||||
|
||||
QByteArrayList envExtList;
|
||||
if (qEnvironmentVariableIsSet("QT_VULKAN_DEVICE_EXTENSIONS")) {
|
||||
envExtList = qgetenv("QT_VULKAN_DEVICE_EXTENSIONS").split(';');
|
||||
for (auto ext : requestedDevExts)
|
||||
envExtList.removeAll(ext);
|
||||
for (const QByteArray &ext : envExtList) {
|
||||
if (!ext.isEmpty())
|
||||
for (const QByteArray &ext : requestedDeviceExtensions) {
|
||||
if (!ext.isEmpty()) {
|
||||
if (devExts.contains(ext))
|
||||
requestedDevExts.append(ext.constData());
|
||||
else
|
||||
qWarning("Device extension %s is not supported", ext.constData());
|
||||
}
|
||||
}
|
||||
|
||||
QByteArrayList envExtList = qgetenv("QT_VULKAN_DEVICE_EXTENSIONS").split(';');
|
||||
for (const QByteArray &ext : envExtList) {
|
||||
if (!ext.isEmpty() && !requestedDevExts.contains(ext)) {
|
||||
if (devExts.contains(ext))
|
||||
requestedDevExts.append(ext.constData());
|
||||
else
|
||||
qWarning("Device extension %s is not supported", ext.constData());
|
||||
}
|
||||
}
|
||||
|
||||
if (QRHI_LOG_INFO().isEnabled(QtDebugMsg)) {
|
||||
qCDebug(QRHI_LOG_INFO, "Enabling device extensions:");
|
||||
for (const char *ext : requestedDevExts)
|
||||
qCDebug(QRHI_LOG_INFO, " %s", ext);
|
||||
}
|
||||
|
||||
VkDeviceCreateInfo devInfo;
|
||||
memset(&devInfo, 0, sizeof(devInfo));
|
||||
devInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
||||
@ -2903,7 +2927,7 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
|
||||
} else if (u.type == QRhiResourceUpdateBatchPrivate::BufferOp::Read) {
|
||||
QVkBuffer *bufD = QRHI_RES(QVkBuffer, u.buf);
|
||||
if (bufD->m_type == QRhiBuffer::Dynamic) {
|
||||
executeBufferHostWritesForCurrentFrame(bufD);
|
||||
executeBufferHostWritesForSlot(bufD, currentFrameSlot);
|
||||
void *p = nullptr;
|
||||
VmaAllocation a = toVmaAllocation(bufD->allocations[currentFrameSlot]);
|
||||
VkResult err = vmaMapMemory(toVmaAllocator(allocator), a, &p);
|
||||
@ -3300,14 +3324,14 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
|
||||
ud->free();
|
||||
}
|
||||
|
||||
void QRhiVulkan::executeBufferHostWritesForCurrentFrame(QVkBuffer *bufD)
|
||||
void QRhiVulkan::executeBufferHostWritesForSlot(QVkBuffer *bufD, int slot)
|
||||
{
|
||||
if (bufD->pendingDynamicUpdates[currentFrameSlot].isEmpty())
|
||||
if (bufD->pendingDynamicUpdates[slot].isEmpty())
|
||||
return;
|
||||
|
||||
Q_ASSERT(bufD->m_type == QRhiBuffer::Dynamic);
|
||||
void *p = nullptr;
|
||||
VmaAllocation a = toVmaAllocation(bufD->allocations[currentFrameSlot]);
|
||||
VmaAllocation a = toVmaAllocation(bufD->allocations[slot]);
|
||||
// The vmaMap/Unmap are basically a no-op when persistently mapped since it
|
||||
// refcounts; this is great because we don't need to care if the allocation
|
||||
// was created as persistently mapped or not.
|
||||
@ -3318,7 +3342,7 @@ void QRhiVulkan::executeBufferHostWritesForCurrentFrame(QVkBuffer *bufD)
|
||||
}
|
||||
int changeBegin = -1;
|
||||
int changeEnd = -1;
|
||||
for (const QRhiResourceUpdateBatchPrivate::BufferOp &u : qAsConst(bufD->pendingDynamicUpdates[currentFrameSlot])) {
|
||||
for (const QRhiResourceUpdateBatchPrivate::BufferOp &u : qAsConst(bufD->pendingDynamicUpdates[slot])) {
|
||||
Q_ASSERT(bufD == QRHI_RES(QVkBuffer, u.buf));
|
||||
memcpy(static_cast<char *>(p) + u.offset, u.data.constData(), size_t(u.data.size()));
|
||||
if (changeBegin == -1 || u.offset < changeBegin)
|
||||
@ -3330,7 +3354,7 @@ void QRhiVulkan::executeBufferHostWritesForCurrentFrame(QVkBuffer *bufD)
|
||||
if (changeBegin >= 0)
|
||||
vmaFlushAllocation(toVmaAllocator(allocator), a, VkDeviceSize(changeBegin), VkDeviceSize(changeEnd - changeBegin));
|
||||
|
||||
bufD->pendingDynamicUpdates[currentFrameSlot].clear();
|
||||
bufD->pendingDynamicUpdates[slot].clear();
|
||||
}
|
||||
|
||||
static void qrhivk_releaseBuffer(const QRhiVulkan::DeferredReleaseEntry &e, void *allocator)
|
||||
@ -4166,7 +4190,7 @@ void QRhiVulkan::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBin
|
||||
Q_ASSERT(bufD->m_usage.testFlag(QRhiBuffer::UniformBuffer));
|
||||
|
||||
if (bufD->m_type == QRhiBuffer::Dynamic)
|
||||
executeBufferHostWritesForCurrentFrame(bufD);
|
||||
executeBufferHostWritesForSlot(bufD, currentFrameSlot);
|
||||
|
||||
bufD->lastActiveFrameSlot = currentFrameSlot;
|
||||
trackedRegisterBuffer(&passResTracker, bufD, bufD->m_type == QRhiBuffer::Dynamic ? currentFrameSlot : 0,
|
||||
@ -4240,7 +4264,7 @@ void QRhiVulkan::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBin
|
||||
Q_ASSERT(bufD->m_usage.testFlag(QRhiBuffer::StorageBuffer));
|
||||
|
||||
if (bufD->m_type == QRhiBuffer::Dynamic)
|
||||
executeBufferHostWritesForCurrentFrame(bufD);
|
||||
executeBufferHostWritesForSlot(bufD, currentFrameSlot);
|
||||
|
||||
bufD->lastActiveFrameSlot = currentFrameSlot;
|
||||
QRhiPassResourceTracker::BufferAccess access;
|
||||
@ -4349,7 +4373,7 @@ void QRhiVulkan::setVertexInput(QRhiCommandBuffer *cb,
|
||||
Q_ASSERT(bufD->m_usage.testFlag(QRhiBuffer::VertexBuffer));
|
||||
bufD->lastActiveFrameSlot = currentFrameSlot;
|
||||
if (bufD->m_type == QRhiBuffer::Dynamic)
|
||||
executeBufferHostWritesForCurrentFrame(bufD);
|
||||
executeBufferHostWritesForSlot(bufD, currentFrameSlot);
|
||||
|
||||
const VkBuffer vkvertexbuf = bufD->buffers[bufD->m_type == QRhiBuffer::Dynamic ? currentFrameSlot : 0];
|
||||
if (cbD->currentVertexBuffers[inputSlot] != vkvertexbuf
|
||||
@ -4395,7 +4419,7 @@ void QRhiVulkan::setVertexInput(QRhiCommandBuffer *cb,
|
||||
Q_ASSERT(ibufD->m_usage.testFlag(QRhiBuffer::IndexBuffer));
|
||||
ibufD->lastActiveFrameSlot = currentFrameSlot;
|
||||
if (ibufD->m_type == QRhiBuffer::Dynamic)
|
||||
executeBufferHostWritesForCurrentFrame(ibufD);
|
||||
executeBufferHostWritesForSlot(ibufD, currentFrameSlot);
|
||||
|
||||
const int slot = ibufD->m_type == QRhiBuffer::Dynamic ? currentFrameSlot : 0;
|
||||
const VkBuffer vkindexbuf = ibufD->buffers[slot];
|
||||
@ -5188,10 +5212,13 @@ bool QVkBuffer::build()
|
||||
QRhiBuffer::NativeBuffer QVkBuffer::nativeBuffer()
|
||||
{
|
||||
if (m_type == Dynamic) {
|
||||
QRHI_RES_RHI(QRhiVulkan);
|
||||
NativeBuffer b;
|
||||
Q_ASSERT(sizeof(b.objects) / sizeof(b.objects[0]) >= size_t(QVK_FRAMES_IN_FLIGHT));
|
||||
for (int i = 0; i < QVK_FRAMES_IN_FLIGHT; ++i)
|
||||
for (int i = 0; i < QVK_FRAMES_IN_FLIGHT; ++i) {
|
||||
rhiD->executeBufferHostWritesForSlot(this, i);
|
||||
b.objects[i] = &buffers[i];
|
||||
}
|
||||
b.slotCount = QVK_FRAMES_IN_FLIGHT;
|
||||
return b;
|
||||
}
|
||||
@ -5536,6 +5563,11 @@ QRhiTexture::NativeTexture QVkTexture::nativeTexture()
|
||||
return {&image, usageState.layout};
|
||||
}
|
||||
|
||||
void QVkTexture::setNativeLayout(int layout)
|
||||
{
|
||||
usageState.layout = VkImageLayout(layout);
|
||||
}
|
||||
|
||||
VkImageView QVkTexture::imageViewForLevel(int level)
|
||||
{
|
||||
Q_ASSERT(level >= 0 && level < int(mipLevelCount));
|
||||
|
@ -57,6 +57,7 @@ struct Q_GUI_EXPORT QRhiVulkanInitParams : public QRhiInitParams
|
||||
{
|
||||
QVulkanInstance *inst = nullptr;
|
||||
QWindow *window = nullptr;
|
||||
QByteArrayList deviceExtensions;
|
||||
};
|
||||
|
||||
struct Q_GUI_EXPORT QRhiVulkanNativeHandles : public QRhiNativeHandles
|
||||
|
@ -123,6 +123,7 @@ struct QVkTexture : public QRhiTexture
|
||||
bool build() override;
|
||||
bool buildFrom(NativeTexture src) override;
|
||||
NativeTexture nativeTexture() override;
|
||||
void setNativeLayout(int layout) override;
|
||||
|
||||
bool prepareBuild(QSize *adjustedSize = nullptr);
|
||||
bool finishBuild();
|
||||
@ -778,7 +779,7 @@ public:
|
||||
size_t *curOfs, void *mp,
|
||||
BufferImageCopyList *copyInfos);
|
||||
void enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdateBatch *resourceUpdates);
|
||||
void executeBufferHostWritesForCurrentFrame(QVkBuffer *bufD);
|
||||
void executeBufferHostWritesForSlot(QVkBuffer *bufD, int slot);
|
||||
void enqueueTransitionPassResources(QVkCommandBuffer *cbD);
|
||||
void recordPrimaryCommandBuffer(QVkCommandBuffer *cbD);
|
||||
void trackedRegisterBuffer(QRhiPassResourceTracker *passResTracker,
|
||||
@ -810,6 +811,7 @@ public:
|
||||
|
||||
QVulkanInstance *inst = nullptr;
|
||||
QWindow *maybeWindow = nullptr;
|
||||
QByteArrayList requestedDeviceExtensions;
|
||||
bool importedDevice = false;
|
||||
VkPhysicalDevice physDev = VK_NULL_HANDLE;
|
||||
VkDevice dev = VK_NULL_HANDLE;
|
||||
|
@ -428,6 +428,7 @@ QShader QShader::fromSerialized(const QByteArray &data)
|
||||
ds >> intVal;
|
||||
d->qsbVersion = intVal;
|
||||
if (d->qsbVersion != QShaderPrivate::QSB_VERSION
|
||||
&& d->qsbVersion != QShaderPrivate::QSB_VERSION_WITHOUT_VAR_ARRAYDIMS
|
||||
&& d->qsbVersion != QShaderPrivate::QSB_VERSION_WITH_CBOR
|
||||
&& d->qsbVersion != QShaderPrivate::QSB_VERSION_WITH_BINARY_JSON
|
||||
&& d->qsbVersion != QShaderPrivate::QSB_VERSION_WITHOUT_BINDINGS)
|
||||
@ -439,7 +440,7 @@ QShader QShader::fromSerialized(const QByteArray &data)
|
||||
ds >> intVal;
|
||||
d->stage = Stage(intVal);
|
||||
if (d->qsbVersion > QShaderPrivate::QSB_VERSION_WITH_CBOR) {
|
||||
d->desc = QShaderDescription::deserialize(&ds);
|
||||
d->desc = QShaderDescription::deserialize(&ds, d->qsbVersion);
|
||||
} else if (d->qsbVersion > QShaderPrivate::QSB_VERSION_WITH_BINARY_JSON) {
|
||||
QByteArray descBin;
|
||||
ds >> descBin;
|
||||
|
@ -57,7 +57,8 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
struct Q_GUI_EXPORT QShaderPrivate
|
||||
{
|
||||
static const int QSB_VERSION = 4;
|
||||
static const int QSB_VERSION = 5;
|
||||
static const int QSB_VERSION_WITHOUT_VAR_ARRAYDIMS = 4;
|
||||
static const int QSB_VERSION_WITH_CBOR = 3;
|
||||
static const int QSB_VERSION_WITH_BINARY_JSON = 2;
|
||||
static const int QSB_VERSION_WITHOUT_BINDINGS = 1;
|
||||
|
@ -35,6 +35,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include "qshaderdescription_p_p.h"
|
||||
#include "qshader_p_p.h"
|
||||
#include <QDebug>
|
||||
#include <QDataStream>
|
||||
#include <QJsonObject>
|
||||
@ -402,10 +403,10 @@ QShaderDescription QShaderDescription::fromCbor(const QByteArray &data)
|
||||
return desc;
|
||||
}
|
||||
|
||||
QShaderDescription QShaderDescription::deserialize(QDataStream *stream)
|
||||
QShaderDescription QShaderDescription::deserialize(QDataStream *stream, int version)
|
||||
{
|
||||
QShaderDescription desc;
|
||||
QShaderDescriptionPrivate::get(&desc)->loadFromStream(stream);
|
||||
QShaderDescriptionPrivate::get(&desc)->loadFromStream(stream, version);
|
||||
return desc;
|
||||
}
|
||||
|
||||
@ -783,6 +784,8 @@ QDebug operator<<(QDebug dbg, const QShaderDescription::InOutVariable &var)
|
||||
dbg.nospace() << " imageFormat=" << imageFormatStr(var.imageFormat);
|
||||
if (var.imageFlags)
|
||||
dbg.nospace() << " imageFlags=" << var.imageFlags;
|
||||
if (!var.arrayDims.isEmpty())
|
||||
dbg.nospace() << " array=" << var.arrayDims;
|
||||
dbg.nospace() << ')';
|
||||
return dbg;
|
||||
}
|
||||
@ -878,6 +881,12 @@ static void addDeco(QJsonObject *obj, const QShaderDescription::InOutVariable &v
|
||||
(*obj)[imageFormatKey] = imageFormatStr(v.imageFormat);
|
||||
if (v.imageFlags)
|
||||
(*obj)[imageFlagsKey] = int(v.imageFlags);
|
||||
if (!v.arrayDims.isEmpty()) {
|
||||
QJsonArray dimArr;
|
||||
for (int dim : v.arrayDims)
|
||||
dimArr.append(dim);
|
||||
(*obj)[arrayDimsKey] = dimArr;
|
||||
}
|
||||
}
|
||||
|
||||
static void serializeDecorations(QDataStream *stream, const QShaderDescription::InOutVariable &v)
|
||||
@ -887,6 +896,9 @@ static void serializeDecorations(QDataStream *stream, const QShaderDescription::
|
||||
(*stream) << v.descriptorSet;
|
||||
(*stream) << int(v.imageFormat);
|
||||
(*stream) << int(v.imageFlags);
|
||||
(*stream) << v.arrayDims.count();
|
||||
for (int dim : v.arrayDims)
|
||||
(*stream) << dim;
|
||||
}
|
||||
|
||||
static QJsonObject inOutObject(const QShaderDescription::InOutVariable &v)
|
||||
@ -1124,10 +1136,15 @@ static QShaderDescription::InOutVariable inOutVar(const QJsonObject &obj)
|
||||
var.imageFormat = mapImageFormat(obj[imageFormatKey].toString());
|
||||
if (obj.contains(imageFlagsKey))
|
||||
var.imageFlags = QShaderDescription::ImageFlags(obj[imageFlagsKey].toInt());
|
||||
if (obj.contains(arrayDimsKey)) {
|
||||
QJsonArray dimArr = obj[arrayDimsKey].toArray();
|
||||
for (int i = 0; i < dimArr.count(); ++i)
|
||||
var.arrayDims.append(dimArr.at(i).toInt());
|
||||
}
|
||||
return var;
|
||||
}
|
||||
|
||||
static void deserializeDecorations(QDataStream *stream, QShaderDescription::InOutVariable *v)
|
||||
static void deserializeDecorations(QDataStream *stream, int version, QShaderDescription::InOutVariable *v)
|
||||
{
|
||||
(*stream) >> v->location;
|
||||
(*stream) >> v->binding;
|
||||
@ -1137,16 +1154,23 @@ static void deserializeDecorations(QDataStream *stream, QShaderDescription::InOu
|
||||
v->imageFormat = QShaderDescription::ImageFormat(f);
|
||||
(*stream) >> f;
|
||||
v->imageFlags = QShaderDescription::ImageFlags(f);
|
||||
|
||||
if (version > QShaderPrivate::QSB_VERSION_WITHOUT_VAR_ARRAYDIMS) {
|
||||
(*stream) >> f;
|
||||
v->arrayDims.resize(f);
|
||||
for (int i = 0; i < f; ++i)
|
||||
(*stream) >> v->arrayDims[i];
|
||||
}
|
||||
}
|
||||
|
||||
static QShaderDescription::InOutVariable deserializeInOutVar(QDataStream *stream)
|
||||
static QShaderDescription::InOutVariable deserializeInOutVar(QDataStream *stream, int version)
|
||||
{
|
||||
QShaderDescription::InOutVariable var;
|
||||
(*stream) >> var.name;
|
||||
int t;
|
||||
(*stream) >> t;
|
||||
var.type = QShaderDescription::VariableType(t);
|
||||
deserializeDecorations(stream, &var);
|
||||
deserializeDecorations(stream, version, &var);
|
||||
return var;
|
||||
}
|
||||
|
||||
@ -1176,7 +1200,7 @@ static QShaderDescription::BlockVariable blockVar(const QJsonObject &obj)
|
||||
return var;
|
||||
}
|
||||
|
||||
static QShaderDescription::BlockVariable deserializeBlockMemberVar(QDataStream *stream)
|
||||
static QShaderDescription::BlockVariable deserializeBlockMemberVar(QDataStream *stream, int version)
|
||||
{
|
||||
QShaderDescription::BlockVariable var;
|
||||
(*stream) >> var.name;
|
||||
@ -1196,7 +1220,7 @@ static QShaderDescription::BlockVariable deserializeBlockMemberVar(QDataStream *
|
||||
(*stream) >> count;
|
||||
var.structMembers.resize(count);
|
||||
for (int i = 0; i < count; ++i)
|
||||
var.structMembers[i] = deserializeBlockMemberVar(stream);
|
||||
var.structMembers[i] = deserializeBlockMemberVar(stream, version);
|
||||
return var;
|
||||
}
|
||||
|
||||
@ -1304,7 +1328,7 @@ void QShaderDescriptionPrivate::loadDoc(const QJsonDocument &doc)
|
||||
}
|
||||
}
|
||||
|
||||
void QShaderDescriptionPrivate::loadFromStream(QDataStream *stream)
|
||||
void QShaderDescriptionPrivate::loadFromStream(QDataStream *stream, int version)
|
||||
{
|
||||
Q_ASSERT(ref.loadRelaxed() == 1); // must be detached
|
||||
|
||||
@ -1312,12 +1336,12 @@ void QShaderDescriptionPrivate::loadFromStream(QDataStream *stream)
|
||||
(*stream) >> count;
|
||||
inVars.resize(count);
|
||||
for (int i = 0; i < count; ++i)
|
||||
inVars[i] = deserializeInOutVar(stream);
|
||||
inVars[i] = deserializeInOutVar(stream, version);
|
||||
|
||||
(*stream) >> count;
|
||||
outVars.resize(count);
|
||||
for (int i = 0; i < count; ++i)
|
||||
outVars[i] = deserializeInOutVar(stream);
|
||||
outVars[i] = deserializeInOutVar(stream, version);
|
||||
|
||||
(*stream) >> count;
|
||||
uniformBlocks.resize(count);
|
||||
@ -1331,7 +1355,7 @@ void QShaderDescriptionPrivate::loadFromStream(QDataStream *stream)
|
||||
(*stream) >> memberCount;
|
||||
uniformBlocks[i].members.resize(memberCount);
|
||||
for (int memberIdx = 0; memberIdx < memberCount; ++memberIdx)
|
||||
uniformBlocks[i].members[memberIdx] = deserializeBlockMemberVar(stream);
|
||||
uniformBlocks[i].members[memberIdx] = deserializeBlockMemberVar(stream, version);
|
||||
}
|
||||
|
||||
(*stream) >> count;
|
||||
@ -1343,7 +1367,7 @@ void QShaderDescriptionPrivate::loadFromStream(QDataStream *stream)
|
||||
(*stream) >> memberCount;
|
||||
pushConstantBlocks[i].members.resize(memberCount);
|
||||
for (int memberIdx = 0; memberIdx < memberCount; ++memberIdx)
|
||||
pushConstantBlocks[i].members[memberIdx] = deserializeBlockMemberVar(stream);
|
||||
pushConstantBlocks[i].members[memberIdx] = deserializeBlockMemberVar(stream, version);
|
||||
}
|
||||
|
||||
(*stream) >> count;
|
||||
@ -1358,7 +1382,7 @@ void QShaderDescriptionPrivate::loadFromStream(QDataStream *stream)
|
||||
(*stream) >> memberCount;
|
||||
storageBlocks[i].members.resize(memberCount);
|
||||
for (int memberIdx = 0; memberIdx < memberCount; ++memberIdx)
|
||||
storageBlocks[i].members[memberIdx] = deserializeBlockMemberVar(stream);
|
||||
storageBlocks[i].members[memberIdx] = deserializeBlockMemberVar(stream, version);
|
||||
}
|
||||
|
||||
(*stream) >> count;
|
||||
@ -1368,7 +1392,7 @@ void QShaderDescriptionPrivate::loadFromStream(QDataStream *stream)
|
||||
int t;
|
||||
(*stream) >> t;
|
||||
combinedImageSamplers[i].type = QShaderDescription::VariableType(t);
|
||||
deserializeDecorations(stream, &combinedImageSamplers[i]);
|
||||
deserializeDecorations(stream, version, &combinedImageSamplers[i]);
|
||||
}
|
||||
|
||||
(*stream) >> count;
|
||||
@ -1378,7 +1402,7 @@ void QShaderDescriptionPrivate::loadFromStream(QDataStream *stream)
|
||||
int t;
|
||||
(*stream) >> t;
|
||||
storageImages[i].type = QShaderDescription::VariableType(t);
|
||||
deserializeDecorations(stream, &storageImages[i]);
|
||||
deserializeDecorations(stream, version, &storageImages[i]);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 3; ++i)
|
||||
@ -1420,7 +1444,8 @@ bool operator==(const QShaderDescription::InOutVariable &lhs, const QShaderDescr
|
||||
&& lhs.binding == rhs.binding
|
||||
&& lhs.descriptorSet == rhs.descriptorSet
|
||||
&& lhs.imageFormat == rhs.imageFormat
|
||||
&& lhs.imageFlags == rhs.imageFlags;
|
||||
&& lhs.imageFlags == rhs.imageFlags
|
||||
&& lhs.arrayDims == rhs.arrayDims;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -78,7 +78,7 @@ public:
|
||||
static QShaderDescription fromBinaryJson(const QByteArray &data);
|
||||
#endif
|
||||
static QShaderDescription fromCbor(const QByteArray &data);
|
||||
static QShaderDescription deserialize(QDataStream *stream);
|
||||
static QShaderDescription deserialize(QDataStream *stream, int version);
|
||||
|
||||
enum VariableType {
|
||||
Unknown = 0,
|
||||
@ -216,6 +216,7 @@ public:
|
||||
int descriptorSet = -1;
|
||||
ImageFormat imageFormat = ImageFormatUnknown;
|
||||
ImageFlags imageFlags;
|
||||
QVector<int> arrayDims;
|
||||
};
|
||||
|
||||
struct BlockVariable {
|
||||
|
@ -82,7 +82,7 @@ struct Q_GUI_EXPORT QShaderDescriptionPrivate
|
||||
QJsonDocument makeDoc();
|
||||
void writeToStream(QDataStream *stream);
|
||||
void loadDoc(const QJsonDocument &doc);
|
||||
void loadFromStream(QDataStream *stream);
|
||||
void loadFromStream(QDataStream *stream, int version);
|
||||
|
||||
QAtomicInt ref;
|
||||
QVector<QShaderDescription::InOutVariable> inVars;
|
||||
|
@ -577,7 +577,10 @@ void QTextMarkdownImporter::insertBlock()
|
||||
QTextBlockFormat blockFormat;
|
||||
if (!m_listStack.isEmpty() && !m_needsInsertList && m_listItem) {
|
||||
QTextList *list = m_listStack.top();
|
||||
blockFormat = list->item(list->count() - 1).blockFormat();
|
||||
if (list)
|
||||
blockFormat = list->item(list->count() - 1).blockFormat();
|
||||
else
|
||||
qWarning() << "attempted to insert into a list that no longer exists";
|
||||
}
|
||||
if (m_blockQuoteDepth) {
|
||||
blockFormat.setProperty(QTextFormat::BlockQuoteLevel, m_blockQuoteDepth);
|
||||
@ -607,7 +610,7 @@ void QTextMarkdownImporter::insertBlock()
|
||||
}
|
||||
if (m_needsInsertList) {
|
||||
m_listStack.push(m_cursor->createList(m_listFormat));
|
||||
} else if (!m_listStack.isEmpty() && m_listItem) {
|
||||
} else if (!m_listStack.isEmpty() && m_listItem && m_listStack.top()) {
|
||||
m_listStack.top()->add(m_cursor->block());
|
||||
}
|
||||
m_needsInsertList = false;
|
||||
|
@ -56,6 +56,7 @@
|
||||
#include <QtGui/qpalette.h>
|
||||
#include <QtGui/qtextdocument.h>
|
||||
#include <QtGui/qtextlist.h>
|
||||
#include <QtCore/qpointer.h>
|
||||
#include <QtCore/qstack.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
@ -113,7 +114,7 @@ private:
|
||||
#endif
|
||||
QString m_blockCodeLanguage;
|
||||
QVector<int> m_nonEmptyTableCells; // in the current row
|
||||
QStack<QTextList *> m_listStack;
|
||||
QStack<QPointer<QTextList>> m_listStack;
|
||||
QStack<QTextCharFormat> m_spanFormatStack;
|
||||
QFont m_monoFont;
|
||||
QPalette m_palette;
|
||||
|
@ -781,6 +781,8 @@ bool QVulkanInstance::supportsPresent(VkPhysicalDevice physicalDevice, uint32_t
|
||||
system dependent synchronization. For example, on Wayland this will
|
||||
add send a wl_surface.frame request in order to prevent the driver from
|
||||
blocking for minimized windows.
|
||||
|
||||
\since 5.15
|
||||
*/
|
||||
void QVulkanInstance::presentAboutToBeQueued(QWindow *window)
|
||||
{
|
||||
|
@ -1595,19 +1595,6 @@ bool QVulkanWindow::event(QEvent *e)
|
||||
\sa setQueueCreateInfoModifier()
|
||||
*/
|
||||
|
||||
/*!
|
||||
Return a previously set queue create info modification function.
|
||||
|
||||
\sa setQueueCreateInfoModifier()
|
||||
|
||||
\since 5.15
|
||||
*/
|
||||
QVulkanWindow::QueueCreateInfoModifier QVulkanWindow::queueCreateInfoModifier() const
|
||||
{
|
||||
Q_D(const QVulkanWindow);
|
||||
return d->queueCreateInfoModifier;
|
||||
}
|
||||
|
||||
/*!
|
||||
Set a queue create info modification function.
|
||||
|
||||
|
@ -106,7 +106,6 @@ public:
|
||||
typedef std::function<void(const VkQueueFamilyProperties *,
|
||||
uint32_t,
|
||||
QVector<VkDeviceQueueCreateInfo> &)> QueueCreateInfoModifier;
|
||||
QueueCreateInfoModifier queueCreateInfoModifier() const;
|
||||
void setQueueCreateInfoModifier(QueueCreateInfoModifier modifier);
|
||||
|
||||
bool isValid() const;
|
||||
|
@ -91,7 +91,7 @@ QNetworkReplyPrivate::QNetworkReplyPrivate()
|
||||
content.
|
||||
|
||||
\note Do not delete the object in the slot connected to the
|
||||
error() or finished() signal. Use deleteLater().
|
||||
errorOccurred() or finished() signal. Use deleteLater().
|
||||
|
||||
\sa QNetworkRequest, QNetworkAccessManager
|
||||
*/
|
||||
@ -219,6 +219,7 @@ QNetworkReplyPrivate::QNetworkReplyPrivate()
|
||||
the server response was detected
|
||||
|
||||
\sa error()
|
||||
\sa errorOccurred()
|
||||
*/
|
||||
|
||||
/*!
|
||||
@ -362,6 +363,14 @@ QNetworkReplyPrivate::QNetworkReplyPrivate()
|
||||
|
||||
/*!
|
||||
\fn void QNetworkReply::error(QNetworkReply::NetworkError code)
|
||||
\obsolete
|
||||
|
||||
Use errorOccurred() instead.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void QNetworkReply::errorOccurred(QNetworkReply::NetworkError code)
|
||||
\since 5.15
|
||||
|
||||
This signal is emitted when the reply detects an error in
|
||||
processing. The finished() signal will probably follow, indicating
|
||||
@ -442,7 +451,7 @@ QNetworkReplyPrivate::QNetworkReplyPrivate()
|
||||
QNetworkAccessManager functions to do that.
|
||||
*/
|
||||
QNetworkReply::QNetworkReply(QObject *parent)
|
||||
: QIODevice(*new QNetworkReplyPrivate, parent)
|
||||
: QNetworkReply(*new QNetworkReplyPrivate, parent)
|
||||
{
|
||||
}
|
||||
|
||||
@ -452,6 +461,8 @@ QNetworkReply::QNetworkReply(QObject *parent)
|
||||
QNetworkReply::QNetworkReply(QNetworkReplyPrivate &dd, QObject *parent)
|
||||
: QIODevice(dd, parent)
|
||||
{
|
||||
// Support the deprecated error() signal:
|
||||
connect(this, &QNetworkReply::errorOccurred, this, QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error));
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -156,7 +156,11 @@ public Q_SLOTS:
|
||||
Q_SIGNALS:
|
||||
void metaDataChanged();
|
||||
void finished();
|
||||
#if QT_DEPRECATED_SINCE(5,15)
|
||||
QT_DEPRECATED_X("Use QNetworkReply::errorOccurred(QNetworkReply::NetworkError) instead")
|
||||
void error(QNetworkReply::NetworkError);
|
||||
#endif
|
||||
void errorOccurred(QNetworkReply::NetworkError);
|
||||
#if QT_CONFIG(ssl)
|
||||
void encrypted();
|
||||
void sslErrors(const QList<QSslError> &errors);
|
||||
|
@ -88,7 +88,7 @@ QNetworkReplyDataImpl::QNetworkReplyDataImpl(QObject *parent, const QNetworkRequ
|
||||
const QString msg = QCoreApplication::translate("QNetworkAccessDataBackend",
|
||||
"Invalid URI: %1").arg(url.toString());
|
||||
setError(QNetworkReply::ProtocolFailure, msg);
|
||||
QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
|
||||
QMetaObject::invokeMethod(this, "errorOccurred", Qt::QueuedConnection,
|
||||
Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ProtocolFailure));
|
||||
QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
|
||||
}
|
||||
|
@ -2253,7 +2253,7 @@ void QNetworkReplyHttpImplPrivate::error(QNetworkReplyImpl::NetworkError code, c
|
||||
// note: might not be a good idea, since users could decide to delete us
|
||||
// which would delete the backend too...
|
||||
// maybe we should protect the backend
|
||||
emit q->error(code);
|
||||
emit q->errorOccurred(code);
|
||||
}
|
||||
|
||||
void QNetworkReplyHttpImplPrivate::_q_metaDataChanged()
|
||||
|
@ -855,7 +855,7 @@ void QNetworkReplyImplPrivate::error(QNetworkReplyImpl::NetworkError code, const
|
||||
// note: might not be a good idea, since users could decide to delete us
|
||||
// which would delete the backend too...
|
||||
// maybe we should protect the backend
|
||||
emit q->error(code);
|
||||
emit q->errorOccurred(code);
|
||||
}
|
||||
|
||||
void QNetworkReplyImplPrivate::metaDataChanged()
|
||||
@ -1128,7 +1128,7 @@ QDisabledNetworkReply::QDisabledNetworkReply(QObject *parent,
|
||||
"Network access is disabled.");
|
||||
setError(UnknownNetworkError, msg);
|
||||
|
||||
QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
|
||||
QMetaObject::invokeMethod(this, "errorOccurred", Qt::QueuedConnection,
|
||||
Q_ARG(QNetworkReply::NetworkError, UnknownNetworkError));
|
||||
QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
|
||||
}
|
||||
|
@ -1215,11 +1215,4 @@ int QGifHandler::currentImageNumber() const
|
||||
return frameNumber;
|
||||
}
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5, 13)
|
||||
QByteArray QGifHandler::name() const
|
||||
{
|
||||
return "gif";
|
||||
}
|
||||
#endif
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -73,10 +73,6 @@ public:
|
||||
bool read(QImage *image) override;
|
||||
bool write(const QImage &image) override;
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5, 13)
|
||||
QByteArray name() const override;
|
||||
#endif
|
||||
|
||||
static bool canRead(QIODevice *device);
|
||||
|
||||
QVariant option(ImageOption option) const override;
|
||||
|
@ -809,17 +809,6 @@ bool QtIcoHandler::write(const QImage &image)
|
||||
return ICOReader::write(device, imgs);
|
||||
}
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5, 13)
|
||||
/*!
|
||||
* Return the common identifier of the format.
|
||||
* For ICO format this will return "ico".
|
||||
*/
|
||||
QByteArray QtIcoHandler::name() const
|
||||
{
|
||||
return "ico";
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! \reimp
|
||||
|
||||
*/
|
||||
|
@ -54,10 +54,6 @@ public:
|
||||
bool read(QImage *image) override;
|
||||
bool write(const QImage &image) override;
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5, 13)
|
||||
QByteArray name() const override;
|
||||
#endif
|
||||
|
||||
int imageCount() const override;
|
||||
bool jumpToImage(int imageNumber) override;
|
||||
bool jumpToNextImage() override;
|
||||
|
@ -1184,11 +1184,4 @@ void QJpegHandler::setOption(ImageOption option, const QVariant &value)
|
||||
}
|
||||
}
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5, 13)
|
||||
QByteArray QJpegHandler::name() const
|
||||
{
|
||||
return "jpeg";
|
||||
}
|
||||
#endif
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -68,10 +68,6 @@ public:
|
||||
bool read(QImage *image) override;
|
||||
bool write(const QImage &image) override;
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5, 13)
|
||||
QByteArray name() const override;
|
||||
#endif
|
||||
|
||||
static bool canRead(QIODevice *device);
|
||||
|
||||
QVariant option(ImageOption option) const override;
|
||||
|
@ -202,9 +202,7 @@ public:
|
||||
const QString &path)
|
||||
: QAbstractFileEngineIterator(filters, nameFilters)
|
||||
{
|
||||
m_stack.push_back(FolderIterator::fromCache(cleanedAssetPath(path), true));
|
||||
if (m_stack.last()->empty())
|
||||
m_stack.pop_back();
|
||||
m_currentIterator = FolderIterator::fromCache(cleanedAssetPath(path), true);
|
||||
}
|
||||
|
||||
QFileInfo currentFileInfo() const override
|
||||
@ -228,36 +226,23 @@ public:
|
||||
|
||||
bool hasNext() const override
|
||||
{
|
||||
if (m_stack.empty())
|
||||
if (!m_currentIterator)
|
||||
return false;
|
||||
if (!m_stack.last()->hasNext()) {
|
||||
m_stack.pop_back();
|
||||
return hasNext();
|
||||
}
|
||||
return true;
|
||||
return m_currentIterator->hasNext();
|
||||
}
|
||||
|
||||
QString next() override
|
||||
{
|
||||
if (m_stack.empty()) {
|
||||
m_currentIterator.reset();
|
||||
if (!m_currentIterator)
|
||||
return {};
|
||||
}
|
||||
m_currentIterator = m_stack.last();
|
||||
auto res = m_currentIterator->next();
|
||||
if (!res)
|
||||
return {};
|
||||
if (res->second.type == AssetItem::Type::Folder) {
|
||||
m_stack.push_back(FolderIterator::fromCache(cleanedAssetPath(currentFilePath()), true));
|
||||
if (m_stack.last()->empty())
|
||||
m_stack.pop_back();
|
||||
}
|
||||
return res->first;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable QSharedPointer<FolderIterator> m_currentIterator;
|
||||
mutable QVector<QSharedPointer<FolderIterator>> m_stack;
|
||||
QSharedPointer<FolderIterator> m_currentIterator;
|
||||
};
|
||||
|
||||
class AndroidAbstractFileEngine: public QAbstractFileEngine
|
||||
|
@ -419,8 +419,7 @@ static QString strippedText(QString s)
|
||||
[mPopUpButton setHidden:chooseDirsOnly]; // TODO hide the whole sunken pane instead?
|
||||
|
||||
if (mOptions->acceptMode() == QFileDialogOptions::AcceptSave) {
|
||||
const QStringList ext = [self acceptableExtensionsForSave];
|
||||
[mSavePanel setAllowedFileTypes:ext.isEmpty() ? nil : qt_mac_QStringListToNSMutableArray(ext)];
|
||||
[self recomputeAcceptableExtensionsForSave];
|
||||
} else {
|
||||
[mOpenPanel setAllowedFileTypes:nil]; // delegate panel:shouldEnableURL: does the file filtering for NSOpenPanel
|
||||
}
|
||||
@ -457,25 +456,49 @@ static QString strippedText(QString s)
|
||||
}
|
||||
|
||||
/*
|
||||
Returns a list of extensions (e.g. "png", "jpg", "gif")
|
||||
for the current name filter. If a filter do not conform
|
||||
to the format *.xyz or * or *.*, an empty list
|
||||
is returned meaning accept everything.
|
||||
Computes a list of extensions (e.g. "png", "jpg", "gif")
|
||||
for the current name filter, and updates the save panel.
|
||||
|
||||
If a filter do not conform to the format *.xyz or * or *.*,
|
||||
all files types are allowed.
|
||||
|
||||
Extensions with more than one part (e.g. "tar.gz") are
|
||||
reduced to their final part, as NSSavePanel does not deal
|
||||
well with multi-part extensions.
|
||||
*/
|
||||
- (QStringList)acceptableExtensionsForSave
|
||||
- (void)recomputeAcceptableExtensionsForSave
|
||||
{
|
||||
QStringList result;
|
||||
for (int i=0; i<mSelectedNameFilter->count(); ++i) {
|
||||
const QString &filter = mSelectedNameFilter->at(i);
|
||||
if (filter.startsWith(QLatin1String("*."))
|
||||
&& !filter.contains(QLatin1Char('?'))
|
||||
&& filter.count(QLatin1Char('*')) == 1) {
|
||||
result += filter.mid(2);
|
||||
} else {
|
||||
return QStringList(); // Accept everything
|
||||
}
|
||||
QStringList fileTypes;
|
||||
for (const QString &filter : *mSelectedNameFilter) {
|
||||
if (!filter.startsWith(QLatin1String("*.")))
|
||||
continue;
|
||||
|
||||
if (filter.contains(QLatin1Char('?')))
|
||||
continue;
|
||||
|
||||
if (filter.count(QLatin1Char('*')) != 1)
|
||||
continue;
|
||||
|
||||
auto extensions = filter.split('.', Qt::SkipEmptyParts);
|
||||
fileTypes += extensions.last();
|
||||
|
||||
// Explicitly show extensions if we detect a filter
|
||||
// that has a multi-part extension. This prevents
|
||||
// confusing situations where the user clicks e.g.
|
||||
// 'foo.tar.gz' and 'foo.tar' is populated in the
|
||||
// file name box, but when then clicking save macOS
|
||||
// will warn that the file needs to end in .gz,
|
||||
// due to thinking the user tried to save the file
|
||||
// as a 'tar' file instead. Unfortunately this
|
||||
// property can only be set before the panel is
|
||||
// shown, so it will not have any effect when
|
||||
// swithcing filters in an already opened dialog.
|
||||
if (extensions.size() > 2)
|
||||
mSavePanel.extensionHidden = NO;
|
||||
}
|
||||
return result;
|
||||
|
||||
mSavePanel.allowedFileTypes = fileTypes.isEmpty() ? nil
|
||||
: qt_mac_QStringListToNSMutableArray(fileTypes);
|
||||
}
|
||||
|
||||
- (QString)removeExtensions:(const QString &)filter
|
||||
|
@ -107,7 +107,7 @@ void *QCocoaNativeInterface::nativeResourceForWindow(const QByteArray &resourceS
|
||||
#if QT_CONFIG(vulkan)
|
||||
} else if (resourceString == "vkSurface") {
|
||||
if (QVulkanInstance *instance = window->vulkanInstance())
|
||||
return static_cast<QCocoaVulkanInstance *>(instance->handle())->createSurface(window);
|
||||
return static_cast<QCocoaVulkanInstance *>(instance->handle())->surface(window);
|
||||
#endif
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -61,9 +61,11 @@ public:
|
||||
|
||||
void createOrAdoptInstance() override;
|
||||
|
||||
VkSurfaceKHR *createSurface(QWindow *window);
|
||||
VkSurfaceKHR createSurface(NSView *view);
|
||||
VkSurfaceKHR *surface(QWindow *window);
|
||||
|
||||
private:
|
||||
VkSurfaceKHR createSurface(NSView *view);
|
||||
|
||||
QVulkanInstance *m_instance = nullptr;
|
||||
QLibrary m_lib;
|
||||
VkSurfaceKHR m_nullSurface = nullptr;
|
||||
|
@ -57,12 +57,11 @@ void QCocoaVulkanInstance::createOrAdoptInstance()
|
||||
initInstance(m_instance, QByteArrayList() << QByteArrayLiteral("VK_MVK_macos_surface"));
|
||||
}
|
||||
|
||||
VkSurfaceKHR *QCocoaVulkanInstance::createSurface(QWindow *window)
|
||||
VkSurfaceKHR *QCocoaVulkanInstance::surface(QWindow *window)
|
||||
{
|
||||
QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
|
||||
if (cocoaWindow->m_vulkanSurface)
|
||||
destroySurface(cocoaWindow->m_vulkanSurface);
|
||||
cocoaWindow->m_vulkanSurface = createSurface(cocoaWindow->m_view);
|
||||
if (!cocoaWindow->m_vulkanSurface)
|
||||
cocoaWindow->m_vulkanSurface = createSurface(cocoaWindow->m_view);
|
||||
return &cocoaWindow->m_vulkanSurface;
|
||||
}
|
||||
|
||||
@ -81,7 +80,7 @@ VkSurfaceKHR QCocoaVulkanInstance::createSurface(NSView *view)
|
||||
surfaceInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
|
||||
surfaceInfo.pNext = nullptr;
|
||||
surfaceInfo.flags = 0;
|
||||
surfaceInfo.pView = view;
|
||||
surfaceInfo.pView = view.layer;
|
||||
|
||||
VkSurfaceKHR surface = nullptr;
|
||||
VkResult err = m_createSurface(m_vkInst, &surfaceInfo, nullptr, &surface);
|
||||
|
@ -394,16 +394,19 @@ QCoreGraphicsPaintEngine::begin(QPaintDevice *pdev)
|
||||
d->cosmeticPenSize = 1;
|
||||
d->current.clipEnabled = false;
|
||||
d->pixelSize = QPoint(1,1);
|
||||
QMacCGContext ctx(pdev);
|
||||
d->hd = CGContextRetain(ctx);
|
||||
if (d->hd) {
|
||||
d->saveGraphicsState();
|
||||
d->orig_xform = CGContextGetCTM(d->hd);
|
||||
if (d->shading) {
|
||||
CGShadingRelease(d->shading);
|
||||
d->shading = nullptr;
|
||||
|
||||
if (pdev->devType() != QInternal::Printer) {
|
||||
QMacCGContext ctx(pdev);
|
||||
d->hd = CGContextRetain(ctx);
|
||||
if (d->hd) {
|
||||
d->saveGraphicsState();
|
||||
d->orig_xform = CGContextGetCTM(d->hd);
|
||||
if (d->shading) {
|
||||
CGShadingRelease(d->shading);
|
||||
d->shading = nullptr;
|
||||
}
|
||||
d->setClip(nullptr); //clear the context's clipping
|
||||
}
|
||||
d->setClip(nullptr); //clear the context's clipping
|
||||
}
|
||||
|
||||
setActive(true);
|
||||
|
@ -343,7 +343,9 @@ QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) cons
|
||||
|
||||
QWindowsWindowData requested;
|
||||
requested.flags = window->flags();
|
||||
requested.geometry = QHighDpi::toNativePixels(window->geometry(), window);
|
||||
requested.geometry = window->isTopLevel()
|
||||
? QHighDpi::toNativePixels(window->geometry(), window)
|
||||
: QHighDpi::toNativeLocalPosition(window->geometry(), window);
|
||||
// Apply custom margins (see QWindowsWindow::setCustomMargins())).
|
||||
const QVariant customMarginsV = window->property("_q_windowsCustomMargins");
|
||||
if (customMarginsV.isValid())
|
||||
|
@ -424,8 +424,12 @@ bool QWindowsSystemTrayIcon::winEvent(const MSG &message, long *result)
|
||||
if (screen) {
|
||||
emit contextMenuRequested(globalPos, screen);
|
||||
emit activated(Context);
|
||||
if (m_menu)
|
||||
if (m_menu) {
|
||||
// Set the foreground window to the controlling window so that clicking outside
|
||||
// of the menu or window will cause the menu to close
|
||||
SetForegroundWindow(m_hwnd);
|
||||
m_menu->trackPopupMenu(message.hwnd, globalPos.x(), globalPos.y());
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1954,10 +1954,8 @@ void QWindowsWindow::checkForScreenChanged(ScreenChangeMode mode)
|
||||
qCDebug(lcQpaWindows).noquote().nospace() << __FUNCTION__
|
||||
<< ' ' << window() << " \"" << (currentScreen ? currentScreen->name() : QString())
|
||||
<< "\"->\"" << newScreen->name() << '"';
|
||||
if (mode == FromGeometryChange)
|
||||
setFlag(SynchronousGeometryChangeEvent);
|
||||
updateFullFrameMargins();
|
||||
QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen());
|
||||
QWindowSystemInterface::handleWindowScreenChanged<QWindowSystemInterface::SynchronousDelivery>(window(), newScreen->screen());
|
||||
}
|
||||
|
||||
void QWindowsWindow::handleGeometryChange()
|
||||
|
@ -274,7 +274,9 @@ void QXcbWindow::create()
|
||||
|
||||
QXcbScreen *currentScreen = xcbScreen();
|
||||
QXcbScreen *platformScreen = parent() ? parentScreen() : initialScreen();
|
||||
QRect rect = QHighDpi::toNativePixels(window()->geometry(), platformScreen);
|
||||
QRect rect = parent()
|
||||
? QHighDpi::toNativeLocalPosition(window()->geometry(), platformScreen)
|
||||
: QHighDpi::toNativePixels(window()->geometry(), platformScreen);
|
||||
|
||||
if (type == Qt::Desktop) {
|
||||
m_window = platformScreen->root();
|
||||
|
@ -131,6 +131,8 @@ void WriteImports::acceptCustomWidget(DomCustomWidget *node)
|
||||
output << "import " << className << '\n';
|
||||
} else { // When we do have elementHeader, we know it's a relative import.
|
||||
QString modulePath = node->elementHeader()->text();
|
||||
// Replace the '/' by '.'
|
||||
modulePath.replace(QLatin1Char('/'), QLatin1Char('.'));
|
||||
// '.h' is added by default on headers for <customwidget>
|
||||
if (modulePath.endsWith(QLatin1String(".h")))
|
||||
modulePath.chop(2);
|
||||
|
@ -1473,6 +1473,9 @@ void QMenuPrivate::_q_actionTriggered()
|
||||
}
|
||||
}
|
||||
activateCausedStack(list, action, QAction::Trigger, false);
|
||||
// if a widget action fires, we need to hide the menu explicitly
|
||||
if (qobject_cast<QWidgetAction*>(action))
|
||||
hideUpToMenuBar();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1640,10 +1643,8 @@ void QMenu::initStyleOption(QStyleOptionMenuItem *option, const QAction *action)
|
||||
|
||||
Widgets can be inserted into menus with the QWidgetAction class.
|
||||
Instances of this class are used to hold widgets, and are inserted
|
||||
into menus with the addAction() overload that takes a QAction.
|
||||
|
||||
Conversely, actions can be added to widgets with the addAction(),
|
||||
addActions() and insertAction() functions.
|
||||
into menus with the addAction() overload that takes a QAction. If the
|
||||
QWidgetAction fires the triggered() signal, the menu will close.
|
||||
|
||||
\warning To make QMenu visible on the screen, exec() or popup() should be
|
||||
used instead of show().
|
||||
|
@ -573,12 +573,32 @@ void tst_QDeadlineTimer::stdchrono()
|
||||
|
||||
QCOMPARE(deadline.remainingTimeAsDuration(), nanoseconds::zero());
|
||||
|
||||
/*
|
||||
Call QTest::qSleep, and return true if the time actually slept is
|
||||
within \a deviationPercent percent of the requested sleep time.
|
||||
Otherwise, return false, in which case the test should to abort.
|
||||
*/
|
||||
auto sleepHelper = [](int ms, int deviationPercent = 10) -> bool {
|
||||
auto before = steady_clock::now();
|
||||
QTest::qSleep(ms);
|
||||
auto after = steady_clock::now();
|
||||
auto diff = duration_cast<milliseconds>(after - before).count();
|
||||
bool inRange = qAbs(diff - ms) < ms * deviationPercent/100.0;
|
||||
if (!inRange)
|
||||
qWarning() << "sleeping" << diff << "instead of" << ms << inRange;
|
||||
return inRange;
|
||||
};
|
||||
|
||||
auto steady_before = steady_clock::now();
|
||||
auto system_before = system_clock::now();
|
||||
|
||||
QTest::qSleep(minResolution);
|
||||
if (!sleepHelper(minResolution))
|
||||
QSKIP("Slept too long");
|
||||
auto now = QDeadlineTimer::current(timerType);
|
||||
QTest::qSleep(minResolution);
|
||||
auto steady_reference = steady_clock::now();
|
||||
auto system_reference = system_clock::now();
|
||||
if (!sleepHelper(minResolution))
|
||||
QSKIP("Slept too long");
|
||||
|
||||
auto sampling_start = steady_clock::now();
|
||||
auto steady_deadline = now.deadline<steady_clock>();
|
||||
@ -599,35 +619,33 @@ void tst_QDeadlineTimer::stdchrono()
|
||||
}
|
||||
|
||||
{
|
||||
auto diff = duration_cast<milliseconds>(steady_after - steady_deadline);
|
||||
QVERIFY2(diff.count() > minResolution/2, QByteArray::number(qint64(diff.count())));
|
||||
QVERIFY2(diff.count() < 3*minResolution/2, QByteArray::number(qint64(diff.count())));
|
||||
auto reference = duration_cast<milliseconds>(steady_after - steady_reference).count();
|
||||
auto diff = duration_cast<milliseconds>(steady_after - steady_deadline).count();
|
||||
QVERIFY2(diff > reference * 0.9 && diff < reference*1.1, QByteArray::number(qint64(diff)));
|
||||
QDeadlineTimer dt_after(steady_after, timerType);
|
||||
QVERIFY2(now < dt_after,
|
||||
("now = " + QLocale().toString(now.deadlineNSecs()) +
|
||||
"; after = " + QLocale().toString(dt_after.deadlineNSecs())).toLatin1());
|
||||
|
||||
diff = duration_cast<milliseconds>(steady_deadline - steady_before);
|
||||
QVERIFY2(diff.count() > minResolution/2, QByteArray::number(qint64(diff.count())));
|
||||
QVERIFY2(diff.count() < 3*minResolution/2, QByteArray::number(qint64(diff.count())));
|
||||
reference = duration_cast<milliseconds>(steady_reference - steady_before).count();
|
||||
diff = duration_cast<milliseconds>(steady_deadline - steady_before).count();
|
||||
QVERIFY2(diff > reference * 0.9 && diff < reference*1.1, QByteArray::number(qint64(diff)));
|
||||
QDeadlineTimer dt_before(steady_before, timerType);
|
||||
QVERIFY2(now > dt_before,
|
||||
("now = " + QLocale().toString(now.deadlineNSecs()) +
|
||||
"; before = " + QLocale().toString(dt_before.deadlineNSecs())).toLatin1());
|
||||
}
|
||||
{
|
||||
auto diff = duration_cast<milliseconds>(system_after - system_deadline);
|
||||
QVERIFY2(diff.count() > minResolution/2, QByteArray::number(qint64(diff.count())));
|
||||
QVERIFY2(diff.count() < 3*minResolution/2, QByteArray::number(qint64(diff.count())));
|
||||
QDeadlineTimer dt_after(system_after, timerType);
|
||||
auto reference = duration_cast<milliseconds>(system_after - system_reference).count();
|
||||
auto diff = duration_cast<milliseconds>(system_after - system_deadline).count();
|
||||
QVERIFY2(diff > reference * 0.9 && diff < reference*1.1, QByteArray::number(qint64(diff))); QDeadlineTimer dt_after(system_after, timerType);
|
||||
QVERIFY2(now < dt_after,
|
||||
("now = " + QLocale().toString(now.deadlineNSecs()) +
|
||||
"; after = " + QLocale().toString(dt_after.deadlineNSecs())).toLatin1());
|
||||
|
||||
diff = duration_cast<milliseconds>(system_deadline - system_before);
|
||||
QVERIFY2(diff.count() > minResolution/2, QByteArray::number(qint64(diff.count())));
|
||||
QVERIFY2(diff.count() < 3*minResolution/2, QByteArray::number(qint64(diff.count())));
|
||||
QDeadlineTimer dt_before(system_before, timerType);
|
||||
reference = duration_cast<milliseconds>(system_reference - system_before).count();
|
||||
diff = duration_cast<milliseconds>(steady_deadline - steady_before).count();
|
||||
QVERIFY2(diff > reference * 0.9 && diff < reference*1.1, QByteArray::number(qint64(diff))); QDeadlineTimer dt_before(system_before, timerType);
|
||||
QVERIFY2(now > dt_before,
|
||||
("now = " + QLocale().toString(now.deadlineNSecs()) +
|
||||
"; before = " + QLocale().toString(dt_before.deadlineNSecs())).toLatin1());
|
||||
|
@ -48,6 +48,7 @@ private Q_SLOTS:
|
||||
void validity();
|
||||
void basics();
|
||||
void elapsed();
|
||||
void msecsTo();
|
||||
};
|
||||
|
||||
void tst_QElapsedTimer::statics()
|
||||
@ -108,30 +109,42 @@ void tst_QElapsedTimer::elapsed()
|
||||
t1.start();
|
||||
|
||||
QTest::qSleep(2*minResolution);
|
||||
|
||||
auto nsecs = t1.nsecsElapsed();
|
||||
auto msecs = t1.elapsed();
|
||||
QVERIFY(nsecs > 0);
|
||||
QVERIFY(msecs > 0);
|
||||
// the number of elapsed nanoseconds and milliseconds should match
|
||||
QVERIFY(nsecs - msecs * 1000000 < 1000000);
|
||||
|
||||
if (msecs > 8 * minResolution)
|
||||
QSKIP("Sampling timer took too long, aborting test");
|
||||
|
||||
QVERIFY(t1.hasExpired(minResolution));
|
||||
QVERIFY(!t1.hasExpired(8*minResolution));
|
||||
QVERIFY(!t1.hasExpired(-1));
|
||||
|
||||
qint64 elapsed = t1.restart();
|
||||
QVERIFY(elapsed >= msecs);
|
||||
QVERIFY(elapsed < msecs + 3*minResolution);
|
||||
}
|
||||
|
||||
void tst_QElapsedTimer::msecsTo()
|
||||
{
|
||||
QElapsedTimer t1;
|
||||
t1.start();
|
||||
QTest::qSleep(minResolution);
|
||||
QElapsedTimer t2;
|
||||
t2.start();
|
||||
|
||||
QVERIFY(t1 != t2);
|
||||
QVERIFY(!(t1 == t2));
|
||||
QVERIFY(t1 < t2);
|
||||
QVERIFY(t1.msecsTo(t2) > 0);
|
||||
|
||||
QVERIFY(t1.nsecsElapsed() > 0);
|
||||
QVERIFY(t1.elapsed() > 0);
|
||||
// the number of elapsed nanoseconds and milliseconds should match
|
||||
QVERIFY(t1.nsecsElapsed() - t1.elapsed() * 1000000 < 1000000);
|
||||
QVERIFY(t1.hasExpired(minResolution));
|
||||
QVERIFY(!t1.hasExpired(8*minResolution));
|
||||
QVERIFY(!t2.hasExpired(minResolution));
|
||||
|
||||
QVERIFY(!t1.hasExpired(-1));
|
||||
QVERIFY(!t2.hasExpired(-1));
|
||||
|
||||
qint64 elapsed = t1.restart();
|
||||
QVERIFY(elapsed > minResolution);
|
||||
QVERIFY(elapsed < 3*minResolution);
|
||||
qint64 diff = t2.msecsTo(t1);
|
||||
QVERIFY(diff < minResolution);
|
||||
auto diff = t1.msecsTo(t2);
|
||||
QVERIFY2(diff > 0, QString("difference t1 and t2 is %1").arg(diff).toLatin1());
|
||||
diff = t2.msecsTo(t1);
|
||||
QVERIFY2(diff < 0, QString("difference t2 and t1 is %1").arg(diff).toLatin1());
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QElapsedTimer);
|
||||
|
@ -5803,6 +5803,8 @@ void tst_QString::split(const QString &string, const QString &sep, QStringList r
|
||||
QVERIFY(list == result);
|
||||
}
|
||||
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_DEPRECATED
|
||||
list = str.split(sep, QString::KeepEmptyParts);
|
||||
QVERIFY(list == result);
|
||||
list = str.split(rx, QString::KeepEmptyParts);
|
||||
@ -5825,6 +5827,7 @@ void tst_QString::split(const QString &string, const QString &sep, QStringList r
|
||||
list = str.split(sep.at(0), QString::SkipEmptyParts);
|
||||
QVERIFY(list == result);
|
||||
}
|
||||
QT_WARNING_POP
|
||||
}
|
||||
|
||||
void tst_QString::split()
|
||||
|
@ -1115,6 +1115,12 @@ void tst_QHash::keyValueIterator()
|
||||
|
||||
entry_type pair(it.key(), it.value());
|
||||
QCOMPARE(*key_value_it, pair);
|
||||
QCOMPARE(key_value_it->first, pair.first);
|
||||
QCOMPARE(key_value_it->second, pair.second);
|
||||
QCOMPARE(&(*key_value_it).first, &it.key());
|
||||
QCOMPARE(&key_value_it->first, &it.key());
|
||||
QCOMPARE(&(*key_value_it).second, &it.value());
|
||||
QCOMPARE(&key_value_it->second, &it.value());
|
||||
++key_value_it;
|
||||
++it;
|
||||
}
|
||||
|
@ -881,6 +881,12 @@ void tst_QMap::keyValueIterator()
|
||||
|
||||
entry_type pair(it.key(), it.value());
|
||||
QCOMPARE(*key_value_it, pair);
|
||||
QCOMPARE(key_value_it->first, pair.first);
|
||||
QCOMPARE(key_value_it->second, pair.second);
|
||||
QCOMPARE(&(*key_value_it).first, &it.key());
|
||||
QCOMPARE(&key_value_it->first, &it.key());
|
||||
QCOMPARE(&(*key_value_it).second, &it.value());
|
||||
QCOMPARE(&key_value_it->second, &it.value());
|
||||
++key_value_it;
|
||||
++it;
|
||||
}
|
||||
|
@ -368,7 +368,7 @@ void tst_QShader::serializeShaderDesc()
|
||||
QBuffer buf(&data);
|
||||
QDataStream ds(&buf);
|
||||
QVERIFY(buf.open(QIODevice::ReadOnly));
|
||||
QShaderDescription desc2 = QShaderDescription::deserialize(&ds);
|
||||
QShaderDescription desc2 = QShaderDescription::deserialize(&ds, QShaderPrivate::QSB_VERSION);
|
||||
QVERIFY(!desc2.isValid());
|
||||
}
|
||||
}
|
||||
@ -400,7 +400,7 @@ void tst_QShader::serializeShaderDesc()
|
||||
QBuffer buf(&data);
|
||||
QDataStream ds(&buf);
|
||||
QVERIFY(buf.open(QIODevice::ReadOnly));
|
||||
QShaderDescription desc2 = QShaderDescription::deserialize(&ds);
|
||||
QShaderDescription desc2 = QShaderDescription::deserialize(&ds, QShaderPrivate::QSB_VERSION);
|
||||
QVERIFY(desc2.isValid());
|
||||
QCOMPARE(desc, desc2);
|
||||
}
|
||||
|
@ -0,0 +1,5 @@
|
||||
<t><EFBFBD>
|
||||
* <20>
|
||||
|
||||
<09>
|
||||
* <20>
|
@ -0,0 +1 @@
|
||||
|
--:|
<?`?><?|`
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user