Merge remote-tracking branch 'origin/5.14' into 5.15

Change-Id: Ie24be82ee70bf103c2664de1a42741979262b10c
This commit is contained in:
Qt Forward Merge Bot 2019-09-16 01:00:07 +02:00
commit 1cfa636fe2
122 changed files with 2510 additions and 1938 deletions

View File

@ -48,12 +48,21 @@
** **
****************************************************************************/ ****************************************************************************/
#include <QtWidgets>
#include "mainwindow.h" #include "mainwindow.h"
#include "encodingdialog.h" #include "encodingdialog.h"
#include "previewform.h" #include "previewform.h"
#include <QAction>
#include <QApplication>
#include <QDesktopWidget>
#include <QFileDialog>
#include <QMenuBar>
#include <QMessageBox>
#include <QPlainTextEdit>
#include <QRegularExpression>
#include <QTextCodec>
#include <QTextStream>
MainWindow::MainWindow() MainWindow::MainWindow()
{ {
textEdit = new QPlainTextEdit; textEdit = new QPlainTextEdit;
@ -146,14 +155,14 @@ void MainWindow::findCodecs()
QTextCodec *codec = QTextCodec::codecForMib(mib); QTextCodec *codec = QTextCodec::codecForMib(mib);
QString sortKey = codec->name().toUpper(); QString sortKey = codec->name().toUpper();
int rank; char rank;
if (sortKey.startsWith(QLatin1String("UTF-8"))) { if (sortKey.startsWith(QLatin1String("UTF-8"))) {
rank = 1; rank = 1;
} else if (sortKey.startsWith(QLatin1String("UTF-16"))) { } else if (sortKey.startsWith(QLatin1String("UTF-16"))) {
rank = 2; rank = 2;
} else if ((match = iso8859RegExp.match(sortKey)).hasMatch()) { } else if ((match = iso8859RegExp.match(sortKey)).hasMatch()) {
if (match.captured(1).size() == 1) if (match.capturedRef(1).size() == 1)
rank = 3; rank = 3;
else else
rank = 4; rank = 4;
@ -164,7 +173,8 @@ void MainWindow::findCodecs()
codecMap.insert(sortKey, codec); codecMap.insert(sortKey, codec);
} }
codecs = codecMap.values(); for (const auto &codec : qAsConst(codecMap))
codecs += codec;
} }
void MainWindow::createMenus() void MainWindow::createMenus()

View File

@ -51,7 +51,7 @@
#ifndef MAINWINDOW_H #ifndef MAINWINDOW_H
#define MAINWINDOW_H #define MAINWINDOW_H
#include <QList> #include <QVector>
#include <QMainWindow> #include <QMainWindow>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -81,10 +81,10 @@ private:
void findCodecs(); void findCodecs();
void createMenus(); void createMenus();
QList<QAction *> saveAsActs; QVector<QAction *> saveAsActs;
QPlainTextEdit *textEdit; QPlainTextEdit *textEdit;
PreviewForm *previewForm; PreviewForm *previewForm;
QList<QTextCodec *> codecs; QVector<QTextCodec *> codecs;
EncodingDialog *m_encodingDialog = nullptr; EncodingDialog *m_encodingDialog = nullptr;
}; };

View File

@ -48,10 +48,19 @@
** **
****************************************************************************/ ****************************************************************************/
#include <QtWidgets>
#include "previewform.h" #include "previewform.h"
#include <QApplication>
#include <QComboBox>
#include <QDesktopWidget>
#include <QDialogButtonBox>
#include <QGridLayout>
#include <QLabel>
#include <QPlainTextEdit>
#include <QPushButton>
#include <QTextCodec>
#include <QTextStream>
// Helpers for creating hex dumps // Helpers for creating hex dumps
static void indent(QTextStream &str, int indent) static void indent(QTextStream &str, int indent)
{ {
@ -83,8 +92,7 @@ static void formatHex(QTextStream &str, const QByteArray &data)
static void formatPrintableCharacters(QTextStream &str, const QByteArray &data) static void formatPrintableCharacters(QTextStream &str, const QByteArray &data)
{ {
for (int i = 0, size = data.size(); i < size; ++i) { for (const char c : data) {
const char c = data.at(i);
switch (c) { switch (c) {
case '\0': case '\0':
str << "\\0"; str << "\\0";
@ -179,7 +187,7 @@ PreviewForm::PreviewForm(QWidget *parent)
resize(screenGeometry.width() * 2 / 5, screenGeometry.height() / 2); resize(screenGeometry.width() * 2 / 5, screenGeometry.height() / 2);
} }
void PreviewForm::setCodecList(const QList<QTextCodec *> &list) void PreviewForm::setCodecList(const QVector<QTextCodec *> &list)
{ {
encodingComboBox->clear(); encodingComboBox->clear();
for (const QTextCodec *codec : list) { for (const QTextCodec *codec : list) {
@ -226,10 +234,10 @@ void PreviewForm::updateTextEdit()
statusLabel->setText(message); statusLabel->setText(message);
statusLabel->setStyleSheet(QStringLiteral("background-color: \"red\";")); statusLabel->setStyleSheet(QStringLiteral("background-color: \"red\";"));
} else if (state.invalidChars) { } else if (state.invalidChars) {
statusLabel->setText(tr("%1: %n invalid characters", 0, state.invalidChars).arg(name)); statusLabel->setText(tr("%1: %n invalid characters", nullptr, state.invalidChars).arg(name));
statusLabel->setStyleSheet(QStringLiteral("background-color: \"yellow\";")); statusLabel->setStyleSheet(QStringLiteral("background-color: \"yellow\";"));
} else { } else {
statusLabel->setText(tr("%1: %n bytes converted", 0, encodedData.size()).arg(name)); statusLabel->setText(tr("%1: %n bytes converted", nullptr, encodedData.size()).arg(name));
statusLabel->setStyleSheet(QString()); statusLabel->setStyleSheet(QString());
} }
if (success) if (success)

View File

@ -52,7 +52,7 @@
#define PREVIEWFORM_H #define PREVIEWFORM_H
#include <QDialog> #include <QDialog>
#include <QList> #include <QVector>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QComboBox; class QComboBox;
@ -71,7 +71,7 @@ class PreviewForm : public QDialog
public: public:
explicit PreviewForm(QWidget *parent = nullptr); explicit PreviewForm(QWidget *parent = nullptr);
void setCodecList(const QList<QTextCodec *> &list); void setCodecList(const QVector<QTextCodec *> &list);
void setEncodedData(const QByteArray &data); void setEncodedData(const QByteArray &data);
QString decodedString() const { return decodedStr; } QString decodedString() const { return decodedStr; }

View File

@ -62,7 +62,7 @@
class FileSystemModel : public QFileSystemModel class FileSystemModel : public QFileSystemModel
{ {
public: public:
FileSystemModel(QObject *parent = 0); FileSystemModel(QObject *parent = nullptr);
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
}; };
//! [0] //! [0]

View File

@ -48,13 +48,28 @@
** **
****************************************************************************/ ****************************************************************************/
#include <QtWidgets>
#include "fsmodel.h"
#include "mainwindow.h" #include "mainwindow.h"
#include "fsmodel.h"
#include <QAction>
#include <QApplication>
#include <QCheckBox>
#include <QComboBox>
#include <QCompleter>
#include <QGridLayout>
#include <QHeaderView>
#include <QLabel>
#include <QLineEdit>
#include <QMenuBar>
#include <QMessageBox>
#include <QSpinBox>
#include <QStandardItemModel>
#include <QStringListModel>
#include <QTreeView>
//! [0] //! [0]
MainWindow::MainWindow(QWidget *parent) MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), completer(0), lineEdit(0) : QMainWindow(parent)
{ {
createMenu(); createMenu();
@ -64,8 +79,8 @@ MainWindow::MainWindow(QWidget *parent)
modelLabel->setText(tr("Model")); modelLabel->setText(tr("Model"));
modelCombo = new QComboBox; modelCombo = new QComboBox;
modelCombo->addItem(tr("QFileSytemModel")); modelCombo->addItem(tr("QFileSystemModel"));
modelCombo->addItem(tr("QFileSytemModel that shows full path")); modelCombo->addItem(tr("QFileSystemModel that shows full path"));
modelCombo->addItem(tr("Country list")); modelCombo->addItem(tr("Country list"));
modelCombo->addItem(tr("Word list")); modelCombo->addItem(tr("Word list"));
modelCombo->setCurrentIndex(0); modelCombo->setCurrentIndex(0);
@ -144,17 +159,17 @@ void MainWindow::createMenu()
connect(aboutAct, &QAction::triggered, this, &MainWindow::about); connect(aboutAct, &QAction::triggered, this, &MainWindow::about);
connect(aboutQtAct, &QAction::triggered, qApp, &QApplication::aboutQt); connect(aboutQtAct, &QAction::triggered, qApp, &QApplication::aboutQt);
QMenu* fileMenu = menuBar()->addMenu(tr("File")); QMenu *fileMenu = menuBar()->addMenu(tr("File"));
fileMenu->addAction(exitAction); fileMenu->addAction(exitAction);
QMenu* helpMenu = menuBar()->addMenu(tr("About")); QMenu *helpMenu = menuBar()->addMenu(tr("About"));
helpMenu->addAction(aboutAct); helpMenu->addAction(aboutAct);
helpMenu->addAction(aboutQtAct); helpMenu->addAction(aboutQtAct);
} }
//! [4] //! [4]
//! [5] //! [5]
QAbstractItemModel *MainWindow::modelFromFile(const QString& fileName) QAbstractItemModel *MainWindow::modelFromFile(const QString &fileName)
{ {
QFile file(fileName); QFile file(fileName);
if (!file.open(QFile::ReadOnly)) if (!file.open(QFile::ReadOnly))
@ -170,7 +185,7 @@ QAbstractItemModel *MainWindow::modelFromFile(const QString& fileName)
while (!file.atEnd()) { while (!file.atEnd()) {
QByteArray line = file.readLine(); QByteArray line = file.readLine();
if (!line.isEmpty()) if (!line.isEmpty())
words << line.trimmed(); words << QString::fromUtf8(line.trimmed());
} }
#ifndef QT_NO_CURSOR #ifndef QT_NO_CURSOR
@ -191,8 +206,8 @@ QAbstractItemModel *MainWindow::modelFromFile(const QString& fileName)
for (int i = 0; i < words.count(); ++i) { for (int i = 0; i < words.count(); ++i) {
QModelIndex countryIdx = m->index(i, 0); QModelIndex countryIdx = m->index(i, 0);
QModelIndex symbolIdx = m->index(i, 1); QModelIndex symbolIdx = m->index(i, 1);
QString country = words[i].mid(0, words[i].length() - 2).trimmed(); QString country = words.at(i).mid(0, words[i].length() - 2).trimmed();
QString symbol = words[i].right(2); QString symbol = words.at(i).right(2);
m->setData(countryIdx, country); m->setData(countryIdx, country);
m->setData(symbolIdx, symbol); m->setData(symbolIdx, symbol);
} }
@ -233,7 +248,7 @@ void MainWindow::changeModel()
case 0: case 0:
{ // Unsorted QFileSystemModel { // Unsorted QFileSystemModel
QFileSystemModel *fsModel = new QFileSystemModel(completer); QFileSystemModel *fsModel = new QFileSystemModel(completer);
fsModel->setRootPath(""); fsModel->setRootPath(QString());
completer->setModel(fsModel); completer->setModel(fsModel);
contentsLabel->setText(tr("Enter file path")); contentsLabel->setText(tr("Enter file path"));
} }
@ -243,7 +258,7 @@ void MainWindow::changeModel()
{ // FileSystemModel that shows full paths { // FileSystemModel that shows full paths
FileSystemModel *fsModel = new FileSystemModel(completer); FileSystemModel *fsModel = new FileSystemModel(completer);
completer->setModel(fsModel); completer->setModel(fsModel);
fsModel->setRootPath(""); fsModel->setRootPath(QString());
contentsLabel->setText(tr("Enter file path")); contentsLabel->setText(tr("Enter file path"));
} }
break; break;

View File

@ -59,7 +59,6 @@ class QComboBox;
class QCompleter; class QCompleter;
class QLabel; class QLabel;
class QLineEdit; class QLineEdit;
class QProgressBar;
class QCheckBox; class QCheckBox;
class QSpinBox; class QSpinBox;
QT_END_NAMESPACE QT_END_NAMESPACE
@ -70,7 +69,7 @@ class MainWindow : public QMainWindow
Q_OBJECT Q_OBJECT
public: public:
MainWindow(QWidget *parent = 0); MainWindow(QWidget *parent = nullptr);
private slots: private slots:
void about(); void about();
@ -83,16 +82,16 @@ private slots:
//! [1] //! [1]
private: private:
void createMenu(); void createMenu();
QAbstractItemModel *modelFromFile(const QString& fileName); QAbstractItemModel *modelFromFile(const QString &fileName);
QComboBox *caseCombo; QComboBox *caseCombo = nullptr;
QComboBox *modeCombo; QComboBox *modeCombo = nullptr;
QComboBox *modelCombo; QComboBox *modelCombo = nullptr;
QSpinBox *maxVisibleSpinBox; QSpinBox *maxVisibleSpinBox = nullptr;
QCheckBox *wrapCheckBox; QCheckBox *wrapCheckBox = nullptr;
QCompleter *completer; QCompleter *completer = nullptr;
QLabel *contentsLabel; QLabel *contentsLabel = nullptr;
QLineEdit *lineEdit; QLineEdit *lineEdit = nullptr;
}; };
//! [1] //! [1]

View File

@ -48,13 +48,20 @@
** **
****************************************************************************/ ****************************************************************************/
#include <QtWidgets>
#include "mainwindow.h" #include "mainwindow.h"
#include "textedit.h" #include "textedit.h"
#include <QAction>
#include <QApplication>
#include <QCompleter>
#include <QFile>
#include <QMenuBar>
#include <QMessageBox>
#include <QStringListModel>
//! [0] //! [0]
MainWindow::MainWindow(QWidget *parent) MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), completer(0) : QMainWindow(parent)
{ {
createMenu(); createMenu();
@ -83,10 +90,10 @@ void MainWindow::createMenu()
connect(aboutAct, &QAction::triggered, this, &MainWindow::about); connect(aboutAct, &QAction::triggered, this, &MainWindow::about);
connect(aboutQtAct, &QAction::triggered, qApp, &QApplication::aboutQt); connect(aboutQtAct, &QAction::triggered, qApp, &QApplication::aboutQt);
QMenu* fileMenu = menuBar()->addMenu(tr("File")); QMenu *fileMenu = menuBar()->addMenu(tr("File"));
fileMenu->addAction(exitAction); fileMenu->addAction(exitAction);
QMenu* helpMenu = menuBar()->addMenu(tr("About")); QMenu *helpMenu = menuBar()->addMenu(tr("About"));
helpMenu->addAction(aboutAct); helpMenu->addAction(aboutAct);
helpMenu->addAction(aboutQtAct); helpMenu->addAction(aboutQtAct);
} }
@ -107,7 +114,7 @@ QAbstractItemModel *MainWindow::modelFromFile(const QString& fileName)
while (!file.atEnd()) { while (!file.atEnd()) {
QByteArray line = file.readLine(); QByteArray line = file.readLine();
if (!line.isEmpty()) if (!line.isEmpty())
words << line.trimmed(); words << QString::fromUtf8(line.trimmed());
} }
#ifndef QT_NO_CURSOR #ifndef QT_NO_CURSOR

View File

@ -55,11 +55,7 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QAbstractItemModel; class QAbstractItemModel;
class QComboBox;
class QCompleter; class QCompleter;
class QLabel;
class QLineEdit;
class QProgressBar;
QT_END_NAMESPACE QT_END_NAMESPACE
class TextEdit; class TextEdit;
@ -69,7 +65,7 @@ class MainWindow : public QMainWindow
Q_OBJECT Q_OBJECT
public: public:
MainWindow(QWidget *parent = 0); MainWindow(QWidget *parent = nullptr);
private slots: private slots:
void about(); void about();
@ -78,7 +74,7 @@ private:
void createMenu(); void createMenu();
QAbstractItemModel *modelFromFile(const QString& fileName); QAbstractItemModel *modelFromFile(const QString& fileName);
QCompleter *completer; QCompleter *completer = nullptr;
TextEdit *completingTextEdit; TextEdit *completingTextEdit;
}; };
//! [0] //! [0]

View File

@ -60,7 +60,7 @@
//! [0] //! [0]
TextEdit::TextEdit(QWidget *parent) TextEdit::TextEdit(QWidget *parent)
: QTextEdit(parent), c(0) : QTextEdit(parent)
{ {
setPlainText(tr("This TextEdit provides autocompletions for words that have more than" setPlainText(tr("This TextEdit provides autocompletions for words that have more than"
" 3 characters. You can trigger autocompletion using ") + " 3 characters. You can trigger autocompletion using ") +
@ -78,7 +78,7 @@ TextEdit::~TextEdit()
void TextEdit::setCompleter(QCompleter *completer) void TextEdit::setCompleter(QCompleter *completer)
{ {
if (c) if (c)
QObject::disconnect(c, 0, this, 0); c->disconnect(this);
c = completer; c = completer;
@ -101,7 +101,7 @@ QCompleter *TextEdit::completer() const
//! [3] //! [3]
//! [4] //! [4]
void TextEdit::insertCompletion(const QString& completion) void TextEdit::insertCompletion(const QString &completion)
{ {
if (c->widget() != this) if (c->widget() != this)
return; return;
@ -150,18 +150,19 @@ void TextEdit::keyPressEvent(QKeyEvent *e)
} }
} }
bool isShortcut = ((e->modifiers() & Qt::ControlModifier) && e->key() == Qt::Key_E); // CTRL+E const bool isShortcut = (e->modifiers().testFlag(Qt::ControlModifier) && e->key() == Qt::Key_E); // CTRL+E
if (!c || !isShortcut) // do not process the shortcut when we have a completer if (!c || !isShortcut) // do not process the shortcut when we have a completer
QTextEdit::keyPressEvent(e); QTextEdit::keyPressEvent(e);
//! [7] //! [7]
//! [8] //! [8]
const bool ctrlOrShift = e->modifiers() & (Qt::ControlModifier | Qt::ShiftModifier); const bool ctrlOrShift = e->modifiers().testFlag(Qt::ControlModifier) ||
e->modifiers().testFlag(Qt::ShiftModifier);
if (!c || (ctrlOrShift && e->text().isEmpty())) if (!c || (ctrlOrShift && e->text().isEmpty()))
return; return;
static QString eow("~!@#$%^&*()_+{}|:\"<>?,./;'[]\\-="); // end of word static QString eow("~!@#$%^&*()_+{}|:\"<>?,./;'[]\\-="); // end of word
bool hasModifier = (e->modifiers() != Qt::NoModifier) && !ctrlOrShift; const bool hasModifier = (e->modifiers() != Qt::NoModifier) && !ctrlOrShift;
QString completionPrefix = textUnderCursor(); QString completionPrefix = textUnderCursor();
if (!isShortcut && (hasModifier || e->text().isEmpty()|| completionPrefix.length() < 3 if (!isShortcut && (hasModifier || e->text().isEmpty()|| completionPrefix.length() < 3

View File

@ -63,7 +63,7 @@ class TextEdit : public QTextEdit
Q_OBJECT Q_OBJECT
public: public:
TextEdit(QWidget *parent = 0); TextEdit(QWidget *parent = nullptr);
~TextEdit(); ~TextEdit();
void setCompleter(QCompleter *c); void setCompleter(QCompleter *c);
@ -80,7 +80,7 @@ private:
QString textUnderCursor() const; QString textUnderCursor() const;
private: private:
QCompleter *c; QCompleter *c = nullptr;
}; };
//! [0] //! [0]

View File

@ -51,13 +51,14 @@
#ifndef ECHOINTERFACE_H #ifndef ECHOINTERFACE_H
#define ECHOINTERFACE_H #define ECHOINTERFACE_H
#include <QObject>
#include <QString> #include <QString>
//! [0] //! [0]
class EchoInterface class EchoInterface
{ {
public: public:
virtual ~EchoInterface() {} virtual ~EchoInterface() = default;
virtual QString echo(const QString &message) = 0; virtual QString echo(const QString &message) = 0;
}; };

View File

@ -48,10 +48,17 @@
** **
****************************************************************************/ ****************************************************************************/
#include <QtWidgets>
#include "echowindow.h" #include "echowindow.h"
#include <QCoreApplication>
#include <QDir>
#include <QLabel>
#include <QLayout>
#include <QLineEdit>
#include <QMessageBox>
#include <QPluginLoader>
#include <QPushButton>
//! [0] //! [0]
EchoWindow::EchoWindow() EchoWindow::EchoWindow()
{ {
@ -101,7 +108,7 @@ void EchoWindow::createGUI()
//! [3] //! [3]
bool EchoWindow::loadPlugin() bool EchoWindow::loadPlugin()
{ {
QDir pluginsDir(qApp->applicationDirPath()); QDir pluginsDir(QCoreApplication::applicationDirPath());
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
if (pluginsDir.dirName().toLower() == "debug" || pluginsDir.dirName().toLower() == "release") if (pluginsDir.dirName().toLower() == "debug" || pluginsDir.dirName().toLower() == "release")
pluginsDir.cdUp(); pluginsDir.cdUp();
@ -121,6 +128,7 @@ bool EchoWindow::loadPlugin()
echoInterface = qobject_cast<EchoInterface *>(plugin); echoInterface = qobject_cast<EchoInterface *>(plugin);
if (echoInterface) if (echoInterface)
return true; return true;
pluginLoader.unload();
} }
} }

View File

@ -48,7 +48,7 @@
** **
****************************************************************************/ ****************************************************************************/
#include <QtWidgets> #include <QApplication>
#include "echowindow.h" #include "echowindow.h"
#include "echointerface.h" #include "echointerface.h"

View File

@ -48,8 +48,6 @@
** **
****************************************************************************/ ****************************************************************************/
#include <QtWidgets>
#include "echoplugin.h" #include "echoplugin.h"
//! [0] //! [0]

View File

@ -48,34 +48,39 @@
** **
****************************************************************************/ ****************************************************************************/
#include <QtWidgets>
#include "languagechooser.h" #include "languagechooser.h"
#include "mainwindow.h" #include "mainwindow.h"
LanguageChooser::LanguageChooser(const QString& defaultLang, QWidget *parent) #include <QCoreApplication>
#include <QCheckBox>
#include <QDialogButtonBox>
#include <QDir>
#include <QGridLayout>
#include <QGroupBox>
#include <QPushButton>
#include <QTranslator>
LanguageChooser::LanguageChooser(const QString &defaultLang, QWidget *parent)
: QDialog(parent, Qt::WindowStaysOnTopHint) : QDialog(parent, Qt::WindowStaysOnTopHint)
{ {
groupBox = new QGroupBox("Languages"); groupBox = new QGroupBox("Languages");
QGridLayout *groupBoxLayout = new QGridLayout; QGridLayout *groupBoxLayout = new QGridLayout;
QStringList qmFiles = findQmFiles(); const QStringList qmFiles = findQmFiles();
for (int i = 0; i < qmFiles.size(); ++i) { for (int i = 0; i < qmFiles.size(); ++i) {
QCheckBox *checkBox = new QCheckBox(languageName(qmFiles[i])); const QString &qmlFile = qmFiles.at(i);
qmFileForCheckBoxMap.insert(checkBox, qmFiles[i]); QCheckBox *checkBox = new QCheckBox(languageName(qmlFile));
connect(checkBox, qmFileForCheckBoxMap.insert(checkBox, qmlFile);
QOverload<bool>::of(&QCheckBox::toggled), connect(checkBox, &QCheckBox::toggled,
this, this, &LanguageChooser::checkBoxToggled);
&LanguageChooser::checkBoxToggled); if (languageMatch(defaultLang, qmlFile))
if (languageMatch(defaultLang, qmFiles[i])) checkBox->setCheckState(Qt::Checked);
checkBox->setCheckState(Qt::Checked);
groupBoxLayout->addWidget(checkBox, i / 2, i % 2); groupBoxLayout->addWidget(checkBox, i / 2, i % 2);
} }
groupBox->setLayout(groupBoxLayout); groupBox->setLayout(groupBoxLayout);
buttonBox = new QDialogButtonBox; buttonBox = new QDialogButtonBox;
showAllButton = buttonBox->addButton("Show All", showAllButton = buttonBox->addButton("Show All",
QDialogButtonBox::ActionRole); QDialogButtonBox::ActionRole);
hideAllButton = buttonBox->addButton("Hide All", hideAllButton = buttonBox->addButton("Hide All",
@ -92,7 +97,7 @@ LanguageChooser::LanguageChooser(const QString& defaultLang, QWidget *parent)
setWindowTitle("I18N"); setWindowTitle("I18N");
} }
bool LanguageChooser::languageMatch(const QString& lang, const QString& qmFile) bool LanguageChooser::languageMatch(const QString &lang, const QString &qmFile)
{ {
//qmFile: i18n_xx.qm //qmFile: i18n_xx.qm
const QString prefix = "i18n_"; const QString prefix = "i18n_";
@ -110,21 +115,21 @@ bool LanguageChooser::eventFilter(QObject *object, QEvent *event)
checkBox->setChecked(false); checkBox->setChecked(false);
} }
} }
return QWidget::eventFilter(object, event); return QDialog::eventFilter(object, event);
} }
void LanguageChooser::closeEvent(QCloseEvent * /* event */) void LanguageChooser::closeEvent(QCloseEvent * /* event */)
{ {
qApp->quit(); QCoreApplication::quit();
} }
void LanguageChooser::checkBoxToggled() void LanguageChooser::checkBoxToggled()
{ {
QCheckBox *checkBox = qobject_cast<QCheckBox *>(sender()); QCheckBox *checkBox = qobject_cast<QCheckBox *>(sender());
MainWindow *window = mainWindowForCheckBoxMap[checkBox]; MainWindow *window = mainWindowForCheckBoxMap.value(checkBox);
if (!window) { if (!window) {
QTranslator translator; QTranslator translator;
translator.load(qmFileForCheckBoxMap[checkBox]); translator.load(qmFileForCheckBoxMap.value(checkBox));
qApp->installTranslator(&translator); qApp->installTranslator(&translator);
window = new MainWindow; window = new MainWindow;

View File

@ -52,7 +52,7 @@
#define LANGUAGECHOOSER_H #define LANGUAGECHOOSER_H
#include <QDialog> #include <QDialog>
#include <QMap> #include <QHash>
#include <QStringList> #include <QStringList>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -68,7 +68,7 @@ class LanguageChooser : public QDialog
Q_OBJECT Q_OBJECT
public: public:
explicit LanguageChooser(const QString& defaultLang = QString(), QWidget *parent = 0); explicit LanguageChooser(const QString &defaultLang = QString(), QWidget *parent = nullptr);
protected: protected:
bool eventFilter(QObject *object, QEvent *event) override; bool eventFilter(QObject *object, QEvent *event) override;
@ -80,17 +80,17 @@ private slots:
void hideAll(); void hideAll();
private: private:
QStringList findQmFiles(); static QStringList findQmFiles();
QString languageName(const QString &qmFile); static QString languageName(const QString &qmFile);
QColor colorForLanguage(const QString &language); static QColor colorForLanguage(const QString &language);
static bool languageMatch(const QString& lang, const QString& qmFile); static bool languageMatch(const QString &lang, const QString &qmFile);
QGroupBox *groupBox; QGroupBox *groupBox;
QDialogButtonBox *buttonBox; QDialogButtonBox *buttonBox;
QAbstractButton *showAllButton; QAbstractButton *showAllButton;
QAbstractButton *hideAllButton; QAbstractButton *hideAllButton;
QMap<QCheckBox *, QString> qmFileForCheckBoxMap; QHash<QCheckBox *, QString> qmFileForCheckBoxMap;
QMap<QCheckBox *, MainWindow *> mainWindowForCheckBoxMap; QHash<QCheckBox *, MainWindow *> mainWindowForCheckBoxMap;
}; };
#endif #endif

View File

@ -48,18 +48,26 @@
** **
****************************************************************************/ ****************************************************************************/
#include <QtWidgets>
#include "mainwindow.h" #include "mainwindow.h"
#include <QAction>
#include <QCoreApplication>
#include <QGroupBox>
#include <QListWidget>
#include <QMenuBar>
#include <QRadioButton>
#include <QStatusBar>
#include <QVBoxLayout>
static const char * const listEntries[] = { static const char * const listEntries[] = {
QT_TRANSLATE_NOOP("MainWindow", "First"), QT_TRANSLATE_NOOP("MainWindow", "First"),
QT_TRANSLATE_NOOP("MainWindow", "Second"), QT_TRANSLATE_NOOP("MainWindow", "Second"),
QT_TRANSLATE_NOOP("MainWindow", "Third"), QT_TRANSLATE_NOOP("MainWindow", "Third"),
0 nullptr
}; };
MainWindow::MainWindow() MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{ {
centralWidget = new QWidget; centralWidget = new QWidget;
setCentralWidget(centralWidget); setCentralWidget(centralWidget);
@ -67,8 +75,8 @@ MainWindow::MainWindow()
createGroupBox(); createGroupBox();
listWidget = new QListWidget; listWidget = new QListWidget;
for (int i = 0; listEntries[i]; ++i) for (const char *entry : listEntries)
listWidget->addItem(tr(listEntries[i])); listWidget->addItem(tr(entry));
QVBoxLayout *mainLayout = new QVBoxLayout; QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addWidget(groupBox); mainLayout->addWidget(groupBox);
@ -76,7 +84,7 @@ MainWindow::MainWindow()
centralWidget->setLayout(mainLayout); centralWidget->setLayout(mainLayout);
exitAction = new QAction(tr("E&xit"), this); exitAction = new QAction(tr("E&xit"), this);
connect(exitAction, &QAction::triggered, qApp, QApplication::quit); connect(exitAction, &QAction::triggered, qApp, QCoreApplication::quit);
fileMenu = menuBar()->addMenu(tr("&File")); fileMenu = menuBar()->addMenu(tr("&File"));
fileMenu->setPalette(QPalette(Qt::red)); fileMenu->setPalette(QPalette(Qt::red));

View File

@ -67,7 +67,7 @@ class MainWindow : public QMainWindow
Q_OBJECT Q_OBJECT
public: public:
MainWindow(); MainWindow(QWidget *parent = nullptr);
private: private:
void createGroupBox(); void createGroupBox();

View File

@ -49,8 +49,8 @@
****************************************************************************/ ****************************************************************************/
#include "interfaces.h"
#include "mainwindow.h" #include "mainwindow.h"
#include "interfaces.h"
#include "paintarea.h" #include "paintarea.h"
#include "plugindialog.h" #include "plugindialog.h"
@ -67,9 +67,8 @@
#include <QScrollArea> #include <QScrollArea>
#include <QTimer> #include <QTimer>
MainWindow::MainWindow() : MainWindow::MainWindow() : paintArea(new PaintArea)
paintArea(new PaintArea), , scrollArea(new QScrollArea)
scrollArea(new QScrollArea)
{ {
scrollArea->setBackgroundRole(QPalette::Dark); scrollArea->setBackgroundRole(QPalette::Dark);
scrollArea->setWidget(paintArea); scrollArea->setWidget(paintArea);
@ -136,7 +135,11 @@ void MainWindow::brushWidth()
void MainWindow::changeBrush() void MainWindow::changeBrush()
{ {
auto action = qobject_cast<QAction *>(sender()); auto action = qobject_cast<QAction *>(sender());
if (!action)
return;
auto iBrush = qobject_cast<BrushInterface *>(action->parent()); auto iBrush = qobject_cast<BrushInterface *>(action->parent());
if (!iBrush)
return;
const QString brush = action->text(); const QString brush = action->text();
paintArea->setBrush(iBrush, brush); paintArea->setBrush(iBrush, brush);
@ -147,7 +150,11 @@ void MainWindow::changeBrush()
void MainWindow::insertShape() void MainWindow::insertShape()
{ {
auto action = qobject_cast<QAction *>(sender()); auto action = qobject_cast<QAction *>(sender());
if (!action)
return;
auto iShape = qobject_cast<ShapeInterface *>(action->parent()); auto iShape = qobject_cast<ShapeInterface *>(action->parent());
if (!iShape)
return;
const QPainterPath path = iShape->generateShape(action->text(), this); const QPainterPath path = iShape->generateShape(action->text(), this);
if (!path.isEmpty()) if (!path.isEmpty())
@ -159,7 +166,11 @@ void MainWindow::insertShape()
void MainWindow::applyFilter() void MainWindow::applyFilter()
{ {
auto action = qobject_cast<QAction *>(sender()); auto action = qobject_cast<QAction *>(sender());
if (!action)
return;
auto iFilter = qobject_cast<FilterInterface *>(action->parent()); auto iFilter = qobject_cast<FilterInterface *>(action->parent());
if (!iFilter)
return;
const QImage image = iFilter->filterImage(action->text(), paintArea->image(), const QImage image = iFilter->filterImage(action->text(), paintArea->image(),
this); this);
@ -247,7 +258,7 @@ void MainWindow::loadPlugins()
populateMenus(plugin); populateMenus(plugin);
//! [4] //! [5] //! [4] //! [5]
pluginsDir = QDir(qApp->applicationDirPath()); pluginsDir = QDir(QCoreApplication::applicationDirPath());
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
if (pluginsDir.dirName().toLower() == "debug" || pluginsDir.dirName().toLower() == "release") if (pluginsDir.dirName().toLower() == "debug" || pluginsDir.dirName().toLower() == "release")

View File

@ -49,14 +49,13 @@
****************************************************************************/ ****************************************************************************/
#include "interfaces.h"
#include "paintarea.h" #include "paintarea.h"
#include "interfaces.h"
#include <QMouseEvent> #include <QMouseEvent>
#include <QPainter> #include <QPainter>
PaintArea::PaintArea(QWidget *parent) : PaintArea::PaintArea(QWidget *parent) : QWidget(parent)
QWidget(parent)
{ {
setAttribute(Qt::WA_StaticContents); setAttribute(Qt::WA_StaticContents);
setAttribute(Qt::WA_OpaquePaintEvent); setAttribute(Qt::WA_OpaquePaintEvent);

View File

@ -49,8 +49,8 @@
****************************************************************************/ ****************************************************************************/
#include "interfaces.h"
#include "plugindialog.h" #include "plugindialog.h"
#include "interfaces.h"
#include <QDir> #include <QDir>
#include <QGridLayout> #include <QGridLayout>

View File

@ -50,10 +50,10 @@
#include "basictoolsplugin.h" #include "basictoolsplugin.h"
#include <QInputDialog>
#include <QPainter>
#include <QRandomGenerator>
#include <QtMath> #include <QtMath>
#include <QtWidgets>
#include <stdlib.h>
//! [0] //! [0]
QStringList BasicToolsPlugin::brushes() const QStringList BasicToolsPlugin::brushes() const

View File

@ -54,12 +54,12 @@
//! [0] //! [0]
#include <interfaces.h> #include <interfaces.h>
#include <QRect>
#include <QObject>
#include <QtPlugin>
#include <QStringList>
#include <QPainterPath>
#include <QImage> #include <QImage>
#include <QObject>
#include <QPainterPath>
#include <QRect>
#include <QStringList>
#include <QtPlugin>
//! [1] //! [1]
class BasicToolsPlugin : public QObject, class BasicToolsPlugin : public QObject,

View File

@ -50,10 +50,7 @@
#include "extrafiltersplugin.h" #include "extrafiltersplugin.h"
#include <QtWidgets> #include <QInputDialog>
#include <math.h>
#include <stdlib.h>
QStringList ExtraFiltersPlugin::filters() const QStringList ExtraFiltersPlugin::filters() const
{ {

View File

@ -65,7 +65,7 @@ class RegExpDialog : public QDialog
Q_OBJECT Q_OBJECT
public: public:
RegExpDialog(QWidget *parent = 0); RegExpDialog(QWidget *parent = nullptr);
private slots: private slots:
void refresh(); void refresh();

View File

@ -70,7 +70,7 @@ class RegularExpressionDialog : public QDialog
Q_OBJECT Q_OBJECT
public: public:
RegularExpressionDialog(QWidget *parent = 0); RegularExpressionDialog(QWidget *parent = nullptr);
private: private:
void refresh(); void refresh();

View File

@ -48,10 +48,20 @@
** **
****************************************************************************/ ****************************************************************************/
#include <QtWidgets>
#include "locationdialog.h" #include "locationdialog.h"
#include <QBoxLayout>
#include <QComboBox>
#include <QDialogButtonBox>
#include <QDir>
#include <QPushButton>
#include <QGroupBox>
#include <QHeaderView>
#include <QLabel>
#include <QLineEdit>
#include <QTableWidget>
#include <QTableWidgetItem>
LocationDialog::LocationDialog(QWidget *parent) LocationDialog::LocationDialog(QWidget *parent)
: QDialog(parent) : QDialog(parent)
{ {
@ -91,8 +101,7 @@ LocationDialog::LocationDialog(QWidget *parent)
locationsGroupBox = new QGroupBox(tr("Setting Locations")); locationsGroupBox = new QGroupBox(tr("Setting Locations"));
QStringList labels; const QStringList labels{tr("Location"), tr("Access")};
labels << tr("Location") << tr("Access");
locationsTable = new QTableWidget; locationsTable = new QTableWidget;
locationsTable->setSelectionMode(QAbstractItemView::SingleSelection); locationsTable->setSelectionMode(QAbstractItemView::SingleSelection);

View File

@ -68,7 +68,7 @@ class LocationDialog : public QDialog
Q_OBJECT Q_OBJECT
public: public:
LocationDialog(QWidget *parent = 0); LocationDialog(QWidget *parent = nullptr);
QSettings::Format format() const; QSettings::Format format() const;
QSettings::Scope scope() const; QSettings::Scope scope() const;

View File

@ -48,15 +48,23 @@
** **
****************************************************************************/ ****************************************************************************/
#include <QtWidgets>
#include "locationdialog.h" #include "locationdialog.h"
#include "mainwindow.h" #include "mainwindow.h"
#include "settingstree.h" #include "settingstree.h"
MainWindow::MainWindow() #include <QAction>
: settingsTree(new SettingsTree) #include <QApplication>
, locationDialog(nullptr) #include <QDesktopWidget>
#include <QFileDialog>
#include <QInputDialog>
#include <QLineEdit>
#include <QMenuBar>
#include <QMessageBox>
#include <QStandardPaths>
#include <QStatusBar>
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
, settingsTree(new SettingsTree)
{ {
setCentralWidget(settingsTree); setCentralWidget(settingsTree);

View File

@ -68,7 +68,7 @@ class MainWindow : public QMainWindow
public: public:
typedef QSharedPointer<QSettings> SettingsPtr; typedef QSharedPointer<QSettings> SettingsPtr;
MainWindow(); MainWindow(QWidget *parent = nullptr);
private slots: private slots:
void openSettings(); void openSettings();
@ -81,11 +81,11 @@ private:
void createActions(); void createActions();
void setSettingsObject(const SettingsPtr &settings); void setSettingsObject(const SettingsPtr &settings);
SettingsTree *settingsTree; SettingsTree *settingsTree = nullptr;
LocationDialog *locationDialog; LocationDialog *locationDialog = nullptr;
QAction *refreshAct; QAction *refreshAct = nullptr;
QAction *autoRefreshAct; QAction *autoRefreshAct = nullptr;
QAction *fallbacksAct; QAction *fallbacksAct = nullptr;
}; };
#endif #endif

View File

@ -48,20 +48,20 @@
** **
****************************************************************************/ ****************************************************************************/
#include <QtWidgets>
#include "settingstree.h" #include "settingstree.h"
#include "variantdelegate.h" #include "variantdelegate.h"
#include <QApplication>
#include <QDesktopWidget>
#include <QHeaderView>
#include <QSettings>
SettingsTree::SettingsTree(QWidget *parent) SettingsTree::SettingsTree(QWidget *parent)
: QTreeWidget(parent) : QTreeWidget(parent)
, autoRefresh(false)
{ {
setItemDelegate(new VariantDelegate(this)); setItemDelegate(new VariantDelegate(this));
QStringList labels; setHeaderLabels({tr("Setting"), tr("Type"), tr("Value")});
labels << tr("Setting") << tr("Type") << tr("Value");
setHeaderLabels(labels);
header()->setSectionResizeMode(0, QHeaderView::ResizeToContents); header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
header()->setSectionResizeMode(1, QHeaderView::ResizeToContents); header()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
header()->setSectionResizeMode(2, QHeaderView::Stretch); header()->setSectionResizeMode(2, QHeaderView::Stretch);
@ -77,10 +77,6 @@ SettingsTree::SettingsTree(QWidget *parent)
connect(&refreshTimer, &QTimer::timeout, this, &SettingsTree::maybeRefresh); connect(&refreshTimer, &QTimer::timeout, this, &SettingsTree::maybeRefresh);
} }
SettingsTree::~SettingsTree()
{
}
void SettingsTree::setSettingsObject(const SettingsPtr &newSettings) void SettingsTree::setSettingsObject(const SettingsPtr &newSettings)
{ {
settings = newSettings; settings = newSettings;
@ -137,7 +133,7 @@ void SettingsTree::refresh()
this, &SettingsTree::updateSetting); this, &SettingsTree::updateSetting);
settings->sync(); settings->sync();
updateChildItems(0); updateChildItems(nullptr);
connect(this, &QTreeWidget::itemChanged, connect(this, &QTreeWidget::itemChanged,
this, &SettingsTree::updateSetting); this, &SettingsTree::updateSetting);
@ -228,7 +224,7 @@ void SettingsTree::updateChildItems(QTreeWidgetItem *parent)
QTreeWidgetItem *SettingsTree::createItem(const QString &text, QTreeWidgetItem *SettingsTree::createItem(const QString &text,
QTreeWidgetItem *parent, int index) QTreeWidgetItem *parent, int index)
{ {
QTreeWidgetItem *after = 0; QTreeWidgetItem *after = nullptr;
if (index != 0) if (index != 0)
after = childAt(parent, index - 1); after = childAt(parent, index - 1);
@ -243,24 +239,18 @@ QTreeWidgetItem *SettingsTree::createItem(const QString &text,
return item; return item;
} }
QTreeWidgetItem *SettingsTree::childAt(QTreeWidgetItem *parent, int index) QTreeWidgetItem *SettingsTree::childAt(QTreeWidgetItem *parent, int index) const
{ {
if (parent) return (parent ? parent->child(index) : topLevelItem(index));
return parent->child(index);
else
return topLevelItem(index);
} }
int SettingsTree::childCount(QTreeWidgetItem *parent) int SettingsTree::childCount(QTreeWidgetItem *parent) const
{ {
if (parent) return (parent ? parent->childCount() : topLevelItemCount());
return parent->childCount();
else
return topLevelItemCount();
} }
int SettingsTree::findChild(QTreeWidgetItem *parent, const QString &text, int SettingsTree::findChild(QTreeWidgetItem *parent, const QString &text,
int startIndex) int startIndex) const
{ {
for (int i = startIndex; i < childCount(parent); ++i) { for (int i = startIndex; i < childCount(parent); ++i) {
if (childAt(parent, i)->text(0) == text) if (childAt(parent, i)->text(0) == text)

View File

@ -65,10 +65,9 @@ class SettingsTree : public QTreeWidget
Q_OBJECT Q_OBJECT
public: public:
typedef QSharedPointer<QSettings> SettingsPtr; using SettingsPtr = QSharedPointer<QSettings>;
SettingsTree(QWidget *parent = 0); SettingsTree(QWidget *parent = nullptr);
~SettingsTree();
void setSettingsObject(const SettingsPtr &settings); void setSettingsObject(const SettingsPtr &settings);
QSize sizeHint() const override; QSize sizeHint() const override;
@ -89,16 +88,16 @@ private:
void updateChildItems(QTreeWidgetItem *parent); void updateChildItems(QTreeWidgetItem *parent);
QTreeWidgetItem *createItem(const QString &text, QTreeWidgetItem *parent, QTreeWidgetItem *createItem(const QString &text, QTreeWidgetItem *parent,
int index); int index);
QTreeWidgetItem *childAt(QTreeWidgetItem *parent, int index); QTreeWidgetItem *childAt(QTreeWidgetItem *parent, int index) const;
int childCount(QTreeWidgetItem *parent); int childCount(QTreeWidgetItem *parent) const;
int findChild(QTreeWidgetItem *parent, const QString &text, int startIndex); int findChild(QTreeWidgetItem *parent, const QString &text, int startIndex) const;
void moveItemForward(QTreeWidgetItem *parent, int oldIndex, int newIndex); void moveItemForward(QTreeWidgetItem *parent, int oldIndex, int newIndex);
SettingsPtr settings; SettingsPtr settings;
QTimer refreshTimer; QTimer refreshTimer;
bool autoRefresh;
QIcon groupIcon; QIcon groupIcon;
QIcon keyIcon; QIcon keyIcon;
bool autoRefresh = false;
}; };
#endif #endif

View File

@ -48,12 +48,14 @@
** **
****************************************************************************/ ****************************************************************************/
#include <QtWidgets>
#include "variantdelegate.h" #include "variantdelegate.h"
#include <QDateTime>
#include <QLineEdit>
#include <QRegularExpressionValidator>
VariantDelegate::VariantDelegate(QObject *parent) VariantDelegate::VariantDelegate(QObject *parent)
: QItemDelegate(parent) : QStyledItemDelegate(parent)
{ {
boolExp.setPattern("true|false"); boolExp.setPattern("true|false");
boolExp.setPatternOptions(QRegularExpression::CaseInsensitiveOption); boolExp.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
@ -82,12 +84,12 @@ void VariantDelegate::paint(QPainter *painter,
if (!isSupportedType(value.type())) { if (!isSupportedType(value.type())) {
QStyleOptionViewItem myOption = option; QStyleOptionViewItem myOption = option;
myOption.state &= ~QStyle::State_Enabled; myOption.state &= ~QStyle::State_Enabled;
QItemDelegate::paint(painter, myOption, index); QStyledItemDelegate::paint(painter, myOption, index);
return; return;
} }
} }
QItemDelegate::paint(painter, option, index); QStyledItemDelegate::paint(painter, option, index);
} }
QWidget *VariantDelegate::createEditor(QWidget *parent, QWidget *VariantDelegate::createEditor(QWidget *parent,
@ -95,11 +97,11 @@ QWidget *VariantDelegate::createEditor(QWidget *parent,
const QModelIndex &index) const const QModelIndex &index) const
{ {
if (index.column() != 2) if (index.column() != 2)
return 0; return nullptr;
QVariant originalValue = index.model()->data(index, Qt::UserRole); QVariant originalValue = index.model()->data(index, Qt::UserRole);
if (!isSupportedType(originalValue.type())) if (!isSupportedType(originalValue.type()))
return 0; return nullptr;
QLineEdit *lineEdit = new QLineEdit(parent); QLineEdit *lineEdit = new QLineEdit(parent);
lineEdit->setFrame(false); lineEdit->setFrame(false);
@ -149,7 +151,7 @@ QWidget *VariantDelegate::createEditor(QWidget *parent,
regExp = unsignedIntegerExp; regExp = unsignedIntegerExp;
break; break;
default: default:
; break;
} }
if (regExp.isValid()) { if (regExp.isValid()) {

View File

@ -51,15 +51,15 @@
#ifndef VARIANTDELEGATE_H #ifndef VARIANTDELEGATE_H
#define VARIANTDELEGATE_H #define VARIANTDELEGATE_H
#include <QItemDelegate> #include <QStyledItemDelegate>
#include <QRegularExpression> #include <QRegularExpression>
class VariantDelegate : public QItemDelegate class VariantDelegate : public QStyledItemDelegate
{ {
Q_OBJECT Q_OBJECT
public: public:
VariantDelegate(QObject *parent = 0); VariantDelegate(QObject *parent = nullptr);
void paint(QPainter *painter, const QStyleOptionViewItem &option, void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const override; const QModelIndex &index) const override;

View File

@ -48,8 +48,6 @@
** **
****************************************************************************/ ****************************************************************************/
#include <QtWidgets>
#include "simplestyle.h" #include "simplestyle.h"
void SimpleStyle::polish(QPalette &palette) void SimpleStyle::polish(QPalette &palette)

View File

@ -53,16 +53,12 @@
#include <QProxyStyle> #include <QProxyStyle>
QT_BEGIN_NAMESPACE
class QPalette;
QT_END_NAMESPACE
class SimpleStyle : public QProxyStyle class SimpleStyle : public QProxyStyle
{ {
Q_OBJECT Q_OBJECT
public: public:
SimpleStyle() {}; SimpleStyle() = default;
void polish(QPalette &palette) override; void polish(QPalette &palette) override;
}; };

View File

@ -48,15 +48,13 @@
** **
****************************************************************************/ ****************************************************************************/
#include <QtWidgets>
#include "simplestyleplugin.h" #include "simplestyleplugin.h"
#include "simplestyle.h" #include "simplestyle.h"
//! [0] //! [0]
QStringList SimpleStylePlugin::keys() const QStringList SimpleStylePlugin::keys() const
{ {
return QStringList() << "SimpleStyle"; return {"SimpleStyle"};
} }
//! [0] //! [0]
@ -65,6 +63,6 @@ QStyle *SimpleStylePlugin::create(const QString &key)
{ {
if (key.toLower() == "simplestyle") if (key.toLower() == "simplestyle")
return new SimpleStyle; return new SimpleStyle;
return 0; return nullptr;
} }
//! [1] //! [1]

View File

@ -53,11 +53,6 @@
#include <QStylePlugin> #include <QStylePlugin>
QT_BEGIN_NAMESPACE
class QStringList;
class QStyle;
QT_END_NAMESPACE
//! [0] //! [0]
class SimpleStylePlugin : public QStylePlugin class SimpleStylePlugin : public QStylePlugin
{ {
@ -65,7 +60,7 @@ class SimpleStylePlugin : public QStylePlugin
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QStyleFactoryInterface" FILE "simplestyle.json") Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QStyleFactoryInterface" FILE "simplestyle.json")
public: public:
SimpleStylePlugin() {} SimpleStylePlugin() = default;
QStringList keys() const; QStringList keys() const;
QStyle *create(const QString &key) override; QStyle *create(const QString &key) override;

View File

@ -48,7 +48,8 @@
** **
****************************************************************************/ ****************************************************************************/
#include <QtWidgets> #include <QApplication>
#include <QStyleFactory>
#include "stylewindow.h" #include "stylewindow.h"

View File

@ -48,7 +48,9 @@
** **
****************************************************************************/ ****************************************************************************/
#include <QtWidgets> #include <QGridLayout>
#include <QGroupBox>
#include <QPushButton>
#include "stylewindow.h" #include "stylewindow.h"

View File

@ -48,13 +48,28 @@
** **
****************************************************************************/ ****************************************************************************/
#include <QtWidgets>
#include "treemodelcompleter.h"
#include "mainwindow.h" #include "mainwindow.h"
#include "treemodelcompleter.h"
#include <QAbstractProxyModel>
#include <QAction>
#include <QApplication>
#include <QCheckBox>
#include <QComboBox>
#include <QFile>
#include <QGridLayout>
#include <QHeaderView>
#include <QLabel>
#include <QLineEdit>
#include <QMenuBar>
#include <QMessageBox>
#include <QStandardItemModel>
#include <QStringListModel>
#include <QTreeView>
//! [0] //! [0]
MainWindow::MainWindow(QWidget *parent) MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), completer(0), lineEdit(0) : QMainWindow(parent)
{ {
createMenu(); createMenu();
@ -151,10 +166,10 @@ void MainWindow::createMenu()
connect(aboutAct, &QAction::triggered, this, &MainWindow::about); connect(aboutAct, &QAction::triggered, this, &MainWindow::about);
connect(aboutQtAct, &QAction::triggered, qApp, &QApplication::aboutQt); connect(aboutQtAct, &QAction::triggered, qApp, &QApplication::aboutQt);
QMenu* fileMenu = menuBar()->addMenu(tr("File")); QMenu *fileMenu = menuBar()->addMenu(tr("File"));
fileMenu->addAction(exitAction); fileMenu->addAction(exitAction);
QMenu* helpMenu = menuBar()->addMenu(tr("About")); QMenu *helpMenu = menuBar()->addMenu(tr("About"));
helpMenu->addAction(aboutAct); helpMenu->addAction(aboutAct);
helpMenu->addAction(aboutQtAct); helpMenu->addAction(aboutQtAct);
} }
@ -175,7 +190,7 @@ void MainWindow::changeMode(int index)
} }
//! [5] //! [5]
QAbstractItemModel *MainWindow::modelFromFile(const QString& fileName) QAbstractItemModel *MainWindow::modelFromFile(const QString &fileName)
{ {
QFile file(fileName); QFile file(fileName);
if (!file.open(QFile::ReadOnly)) if (!file.open(QFile::ReadOnly))
@ -184,39 +199,35 @@ QAbstractItemModel *MainWindow::modelFromFile(const QString& fileName)
#ifndef QT_NO_CURSOR #ifndef QT_NO_CURSOR
QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
#endif #endif
QStringList words;
QStandardItemModel *model = new QStandardItemModel(completer); QStandardItemModel *model = new QStandardItemModel(completer);
QVector<QStandardItem *> parents(10); QVector<QStandardItem *> parents(10);
parents[0] = model->invisibleRootItem(); parents[0] = model->invisibleRootItem();
QRegularExpression re("^\\s+");
while (!file.atEnd()) { while (!file.atEnd()) {
QString line = file.readLine(); const QString line = QString::fromUtf8(file.readLine()).trimmed();
QString trimmedLine = line.trimmed(); const QString trimmedLine = line.trimmed();
if (line.isEmpty() || trimmedLine.isEmpty()) if (trimmedLine.isEmpty())
continue; continue;
QRegularExpression re("^\\s+"); const QRegularExpressionMatch match = re.match(line);
QRegularExpressionMatch match = re.match(line);
int nonws = match.capturedStart(); int nonws = match.capturedStart();
int level = 0; int level = 0;
if (nonws == -1) { if (nonws == -1) {
level = 0; level = 0;
} else { } else {
if (line.startsWith("\t")) { const int capLen = match.capturedLength();
level = match.capturedLength(); level = line.startsWith(QLatin1Char('\t')) ? capLen / 4 : capLen;
} else {
level = match.capturedLength()/4;
}
} }
if (level+1 >= parents.size()) if (level + 1 >= parents.size())
parents.resize(parents.size()*2); parents.resize(parents.size() * 2);
QStandardItem *item = new QStandardItem; QStandardItem *item = new QStandardItem;
item->setText(trimmedLine); item->setText(trimmedLine);
parents[level]->appendRow(item); parents[level]->appendRow(item);
parents[level+1] = item; parents[level + 1] = item;
} }
#ifndef QT_NO_CURSOR #ifndef QT_NO_CURSOR
@ -252,7 +263,7 @@ void MainWindow::changeCase(int cs)
} }
//! [7] //! [7]
void MainWindow::updateContentsLabel(const QString& sep) void MainWindow::updateContentsLabel(const QString &sep)
{ {
contentsLabel->setText(tr("Type path from model above with items at each level separated by a '%1'").arg(sep)); contentsLabel->setText(tr("Type path from model above with items at each level separated by a '%1'").arg(sep));
} }

View File

@ -60,8 +60,6 @@ class QAbstractItemModel;
class QComboBox; class QComboBox;
class QLabel; class QLabel;
class QLineEdit; class QLineEdit;
class QProgressBar;
class QCheckBox;
class QTreeView; class QTreeView;
QT_END_NAMESPACE QT_END_NAMESPACE
@ -71,27 +69,27 @@ class MainWindow : public QMainWindow
Q_OBJECT Q_OBJECT
public: public:
MainWindow(QWidget *parent = 0); MainWindow(QWidget *parent = nullptr);
private slots: private slots:
void about(); void about();
void changeCase(int); void changeCase(int);
void changeMode(int); void changeMode(int);
void highlight(const QModelIndex&); void highlight(const QModelIndex &index);
void updateContentsLabel(const QString&); void updateContentsLabel(const QString &sep);
//! [0] //! [0]
//! [1] //! [1]
private: private:
void createMenu(); void createMenu();
QAbstractItemModel *modelFromFile(const QString& fileName); QAbstractItemModel *modelFromFile(const QString &fileName);
QTreeView *treeView; QTreeView *treeView = nullptr;
QComboBox *caseCombo; QComboBox *caseCombo = nullptr;
QComboBox *modeCombo; QComboBox *modeCombo = nullptr;
QLabel *contentsLabel; QLabel *contentsLabel = nullptr;
TreeModelCompleter *completer; TreeModelCompleter *completer = nullptr;
QLineEdit *lineEdit; QLineEdit *lineEdit = nullptr;
}; };
//! [1] //! [1]

View File

@ -80,26 +80,20 @@ QString TreeModelCompleter::separator() const
//! [3] //! [3]
QStringList TreeModelCompleter::splitPath(const QString &path) const QStringList TreeModelCompleter::splitPath(const QString &path) const
{ {
if (sep.isNull()) { return (sep.isNull() ? QCompleter::splitPath(path) : path.split(sep));
return QCompleter::splitPath(path);
}
return path.split(sep);
} }
//! [3] //! [3]
//! [4] //! [4]
QString TreeModelCompleter::pathFromIndex(const QModelIndex &index) const QString TreeModelCompleter::pathFromIndex(const QModelIndex &index) const
{ {
if (sep.isNull()) { if (sep.isNull())
return QCompleter::pathFromIndex(index); return QCompleter::pathFromIndex(index);
}
// navigate up and accumulate data // navigate up and accumulate data
QStringList dataList; QStringList dataList;
for (QModelIndex i = index; i.isValid(); i = i.parent()) { for (QModelIndex i = index; i.isValid(); i = i.parent())
dataList.prepend(model()->data(i, completionRole()).toString()); dataList.prepend(model()->data(i, completionRole()).toString());
}
return dataList.join(sep); return dataList.join(sep);
} }

View File

@ -60,8 +60,8 @@ class TreeModelCompleter : public QCompleter
Q_PROPERTY(QString separator READ separator WRITE setSeparator) Q_PROPERTY(QString separator READ separator WRITE setSeparator)
public: public:
explicit TreeModelCompleter(QObject *parent = 0); explicit TreeModelCompleter(QObject *parent = nullptr);
explicit TreeModelCompleter(QAbstractItemModel *model, QObject *parent = 0); explicit TreeModelCompleter(QAbstractItemModel *model, QObject *parent = nullptr);
QString separator() const; QString separator() const;
public slots: public slots:

View File

@ -50,18 +50,16 @@
#include "commands.h" #include "commands.h"
static const int setShapeRectCommandId = 1; static constexpr int setShapeRectCommandId = 1;
static const int setShapeColorCommandId = 2; static constexpr int setShapeColorCommandId = 2;
/****************************************************************************** /******************************************************************************
** AddShapeCommand ** AddShapeCommand
*/ */
AddShapeCommand::AddShapeCommand(Document *doc, const Shape &shape, QUndoCommand *parent) AddShapeCommand::AddShapeCommand(Document *doc, const Shape &shape, QUndoCommand *parent)
: QUndoCommand(parent) : QUndoCommand(parent), m_doc(doc), m_shape(shape)
{ {
m_doc = doc;
m_shape = shape;
} }
void AddShapeCommand::undo() void AddShapeCommand::undo()
@ -81,13 +79,11 @@ void AddShapeCommand::redo()
*/ */
RemoveShapeCommand::RemoveShapeCommand(Document *doc, const QString &shapeName, RemoveShapeCommand::RemoveShapeCommand(Document *doc, const QString &shapeName,
QUndoCommand *parent) QUndoCommand *parent)
: QUndoCommand(parent) : QUndoCommand(parent), m_doc(doc), m_shape(doc->shape(shapeName))
, m_shapeName(shapeName)
{ {
setText(QObject::tr("Remove %1").arg(shapeName)); setText(QObject::tr("Remove %1").arg(shapeName));
m_doc = doc;
m_shape = doc->shape(shapeName);
m_shapeName = shapeName;
} }
void RemoveShapeCommand::undo() void RemoveShapeCommand::undo()
@ -105,15 +101,11 @@ void RemoveShapeCommand::redo()
*/ */
SetShapeColorCommand::SetShapeColorCommand(Document *doc, const QString &shapeName, SetShapeColorCommand::SetShapeColorCommand(Document *doc, const QString &shapeName,
const QColor &color, QUndoCommand *parent) const QColor &color, QUndoCommand *parent)
: QUndoCommand(parent) : QUndoCommand(parent), m_doc(doc), m_shapeName(shapeName)
, m_oldColor(doc->shape(shapeName).color()), m_newColor(color)
{ {
setText(QObject::tr("Set %1's color").arg(shapeName)); setText(QObject::tr("Set %1's color").arg(shapeName));
m_doc = doc;
m_shapeName = shapeName;
m_oldColor = doc->shape(shapeName).color();
m_newColor = color;
} }
void SetShapeColorCommand::undo() void SetShapeColorCommand::undo()
@ -149,15 +141,11 @@ int SetShapeColorCommand::id() const
*/ */
SetShapeRectCommand::SetShapeRectCommand(Document *doc, const QString &shapeName, SetShapeRectCommand::SetShapeRectCommand(Document *doc, const QString &shapeName,
const QRect &rect, QUndoCommand *parent) const QRect &rect, QUndoCommand *parent)
: QUndoCommand(parent) : QUndoCommand(parent), m_doc(doc), m_shapeName(shapeName)
, m_oldRect(doc->shape(shapeName).rect()), m_newRect(rect)
{ {
setText(QObject::tr("Change %1's geometry").arg(shapeName)); setText(QObject::tr("Change %1's geometry").arg(shapeName));
m_doc = doc;
m_shapeName = shapeName;
m_oldRect = doc->shape(shapeName).rect();
m_newRect = rect;
} }
void SetShapeRectCommand::undo() void SetShapeRectCommand::undo()

View File

@ -57,7 +57,8 @@
class AddShapeCommand : public QUndoCommand class AddShapeCommand : public QUndoCommand
{ {
public: public:
AddShapeCommand(Document *doc, const Shape &shape, QUndoCommand *parent = 0); AddShapeCommand(Document *doc, const Shape &shape,
QUndoCommand *parent = nullptr);
void undo() override; void undo() override;
void redo() override; void redo() override;
@ -70,7 +71,8 @@ private:
class RemoveShapeCommand : public QUndoCommand class RemoveShapeCommand : public QUndoCommand
{ {
public: public:
RemoveShapeCommand(Document *doc, const QString &shapeName, QUndoCommand *parent = 0); RemoveShapeCommand(Document *doc, const QString &shapeName,
QUndoCommand *parent = nullptr);
void undo() override; void undo() override;
void redo() override; void redo() override;
@ -83,8 +85,8 @@ private:
class SetShapeColorCommand : public QUndoCommand class SetShapeColorCommand : public QUndoCommand
{ {
public: public:
SetShapeColorCommand(Document *doc, const QString &shapeName, const QColor &color, SetShapeColorCommand(Document *doc, const QString &shapeName,
QUndoCommand *parent = 0); const QColor &color, QUndoCommand *parent = nullptr);
void undo() override; void undo() override;
void redo() override; void redo() override;
@ -102,8 +104,8 @@ private:
class SetShapeRectCommand : public QUndoCommand class SetShapeRectCommand : public QUndoCommand
{ {
public: public:
SetShapeRectCommand(Document *doc, const QString &shapeName, const QRect &rect, SetShapeRectCommand(Document *doc, const QString &shapeName,
QUndoCommand *parent = 0); const QRect &rect, QUndoCommand *parent = nullptr);
void undo() override; void undo() override;
void redo() override; void redo() override;

View File

@ -48,14 +48,15 @@
** **
****************************************************************************/ ****************************************************************************/
#include <qevent.h>
#include <QPainter>
#include <QTextStream>
#include <QUndoStack>
#include "document.h" #include "document.h"
#include "commands.h" #include "commands.h"
static const int resizeHandleWidth = 6; #include <QPainter>
#include <QPaintEvent>
#include <QTextStream>
#include <QUndoStack>
static constexpr int resizeHandleWidth = 6;
/****************************************************************************** /******************************************************************************
** Shape ** Shape
@ -96,26 +97,21 @@ QRect Shape::resizeHandle() const
QString Shape::typeToString(Type type) QString Shape::typeToString(Type type)
{ {
QString result;
switch (type) { switch (type) {
case Rectangle: case Rectangle:
result = QLatin1String("Rectangle"); return QLatin1String("Rectangle");
break;
case Circle: case Circle:
result = QLatin1String("Circle"); return QLatin1String("Circle");
break;
case Triangle: case Triangle:
result = QLatin1String("Triangle"); return QLatin1String("Triangle");
break;
} }
return result; return QString();
} }
Shape::Type Shape::stringToType(const QString &s, bool *ok) Shape::Type Shape::stringToType(const QString &s, bool *ok)
{ {
if (ok != 0) if (ok != nullptr)
*ok = true; *ok = true;
if (s == QLatin1String("Rectangle")) if (s == QLatin1String("Rectangle"))
@ -125,7 +121,7 @@ Shape::Type Shape::stringToType(const QString &s, bool *ok)
if (s == QLatin1String("Triangle")) if (s == QLatin1String("Triangle"))
return Triangle; return Triangle;
if (ok != 0) if (ok != nullptr)
*ok = false; *ok = false;
return Rectangle; return Rectangle;
} }
@ -135,10 +131,8 @@ Shape::Type Shape::stringToType(const QString &s, bool *ok)
*/ */
Document::Document(QWidget *parent) Document::Document(QWidget *parent)
: QWidget(parent), m_currentIndex(-1), m_mousePressIndex(-1), m_resizeHandlePressed(false) : QWidget(parent), m_undoStack(new QUndoStack(this))
{ {
m_undoStack = new QUndoStack(this);
setAutoFillBackground(true); setAutoFillBackground(true);
setBackgroundRole(QPalette::Base); setBackgroundRole(QPalette::Base);

View File

@ -70,7 +70,7 @@ public:
QColor color() const; QColor color() const;
static QString typeToString(Type type); static QString typeToString(Type type);
static Type stringToType(const QString &s, bool *ok = 0); static Type stringToType(const QString &s, bool *ok = nullptr);
static const QSize minSize; static const QSize minSize;
@ -88,7 +88,7 @@ class Document : public QWidget
Q_OBJECT Q_OBJECT
public: public:
Document(QWidget *parent = 0); Document(QWidget *parent = nullptr);
QString addShape(const Shape &shape); QString addShape(const Shape &shape);
void deleteShape(const QString &shapeName); void deleteShape(const QString &shapeName);
@ -121,14 +121,13 @@ private:
int indexAt(const QPoint &pos) const; int indexAt(const QPoint &pos) const;
QString uniqueName(const QString &name) const; QString uniqueName(const QString &name) const;
QList<Shape> m_shapeList; QVector<Shape> m_shapeList;
int m_currentIndex;
int m_mousePressIndex;
QPoint m_mousePressOffset; QPoint m_mousePressOffset;
bool m_resizeHandlePressed;
QString m_fileName; QString m_fileName;
QUndoStack *m_undoStack = nullptr;
QUndoStack *m_undoStack; int m_currentIndex = -1;
int m_mousePressIndex = -1;
bool m_resizeHandlePressed = false;
}; };
#endif // DOCUMENT_H #endif // DOCUMENT_H

View File

@ -48,6 +48,10 @@
** **
****************************************************************************/ ****************************************************************************/
#include "mainwindow.h"
#include "document.h"
#include "commands.h"
#include <QUndoGroup> #include <QUndoGroup>
#include <QUndoStack> #include <QUndoStack>
#include <QFileDialog> #include <QFileDialog>
@ -55,9 +59,6 @@
#include <QRandomGenerator> #include <QRandomGenerator>
#include <QTextStream> #include <QTextStream>
#include <QToolButton> #include <QToolButton>
#include "document.h"
#include "mainwindow.h"
#include "commands.h"
MainWindow::MainWindow(QWidget *parent) MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent) : QMainWindow(parent)
@ -122,17 +123,17 @@ MainWindow::MainWindow(QWidget *parent)
void MainWindow::updateActions() void MainWindow::updateActions()
{ {
Document *doc = currentDocument(); Document *doc = currentDocument();
m_undoGroup->setActiveStack(doc == 0 ? 0 : doc->undoStack()); m_undoGroup->setActiveStack(doc == nullptr ? nullptr : doc->undoStack());
QString shapeName = doc == 0 ? QString() : doc->currentShapeName(); QString shapeName = doc == nullptr ? QString() : doc->currentShapeName();
actionAddRobot->setEnabled(doc != 0); actionAddRobot->setEnabled(doc != nullptr);
actionAddSnowman->setEnabled(doc != 0); actionAddSnowman->setEnabled(doc != nullptr);
actionAddCircle->setEnabled(doc != 0); actionAddCircle->setEnabled(doc != nullptr);
actionAddRectangle->setEnabled(doc != 0); actionAddRectangle->setEnabled(doc != nullptr);
actionAddTriangle->setEnabled(doc != 0); actionAddTriangle->setEnabled(doc != nullptr);
actionClose->setEnabled(doc != 0); actionClose->setEnabled(doc != nullptr);
actionSave->setEnabled(doc != 0 && !doc->undoStack()->isClean()); actionSave->setEnabled(doc != nullptr && !doc->undoStack()->isClean());
undoLimit->setEnabled(doc != 0 && doc->undoStack()->count() == 0); undoLimit->setEnabled(doc != nullptr && doc->undoStack()->count() == 0);
if (shapeName.isEmpty()) { if (shapeName.isEmpty()) {
actionRed->setEnabled(false); actionRed->setEnabled(false);
@ -147,7 +148,7 @@ void MainWindow::updateActions()
actionRemoveShape->setEnabled(true); actionRemoveShape->setEnabled(true);
} }
if (doc != 0) { if (doc != nullptr) {
int index = documentTabs->indexOf(doc); int index = documentTabs->indexOf(doc);
Q_ASSERT(index != -1); Q_ASSERT(index != -1);
static const QIcon unsavedIcon(":/icons/filesave.png"); static const QIcon unsavedIcon(":/icons/filesave.png");
@ -264,7 +265,7 @@ void MainWindow::removeDocument(Document *doc)
void MainWindow::saveDocument() void MainWindow::saveDocument()
{ {
Document *doc = currentDocument(); Document *doc = currentDocument();
if (doc == 0) if (doc == nullptr)
return; return;
for (;;) { for (;;) {
@ -298,7 +299,7 @@ void MainWindow::saveDocument()
void MainWindow::closeDocument() void MainWindow::closeDocument()
{ {
Document *doc = currentDocument(); Document *doc = currentDocument();
if (doc == 0) if (doc == nullptr)
return; return;
if (!doc->undoStack()->isClean()) { if (!doc->undoStack()->isClean()) {
@ -338,10 +339,10 @@ static QRect randomRect(const QSize &s)
{ {
QSize min = Shape::minSize; QSize min = Shape::minSize;
int left = (int) ((0.0 + s.width() - min.width())*(QRandomGenerator::global()->bounded(1.0))); int left = qRound((s.width() - min.width()) * (QRandomGenerator::global()->bounded(1.0)));
int top = (int) ((0.0 + s.height() - min.height())*(QRandomGenerator::global()->bounded(1.0))); int top = qRound((s.height() - min.height()) * (QRandomGenerator::global()->bounded(1.0)));
int width = (int) ((0.0 + s.width() - left - min.width())*(QRandomGenerator::global()->bounded(1.0))) + min.width(); int width = qRound((s.width() - left - min.width()) * (QRandomGenerator::global()->bounded(1.0))) + min.width();
int height = (int) ((0.0 + s.height() - top - min.height())*(QRandomGenerator::global()->bounded(1.0))) + min.height(); int height = qRound((s.height() - top - min.height()) * (QRandomGenerator::global()->bounded(1.0))) + min.height();
return QRect(left, top, width, height); return QRect(left, top, width, height);
} }
@ -349,7 +350,7 @@ static QRect randomRect(const QSize &s)
void MainWindow::addShape() void MainWindow::addShape()
{ {
Document *doc = currentDocument(); Document *doc = currentDocument();
if (doc == 0) if (doc == nullptr)
return; return;
Shape::Type type; Shape::Type type;
@ -369,7 +370,7 @@ void MainWindow::addShape()
void MainWindow::removeShape() void MainWindow::removeShape()
{ {
Document *doc = currentDocument(); Document *doc = currentDocument();
if (doc == 0) if (doc == nullptr)
return; return;
QString shapeName = doc->currentShapeName(); QString shapeName = doc->currentShapeName();
@ -382,7 +383,7 @@ void MainWindow::removeShape()
void MainWindow::setShapeColor() void MainWindow::setShapeColor()
{ {
Document *doc = currentDocument(); Document *doc = currentDocument();
if (doc == 0) if (doc == nullptr)
return; return;
QString shapeName = doc->currentShapeName(); QString shapeName = doc->currentShapeName();
@ -409,7 +410,7 @@ void MainWindow::setShapeColor()
void MainWindow::addSnowman() void MainWindow::addSnowman()
{ {
Document *doc = currentDocument(); Document *doc = currentDocument();
if (doc == 0) if (doc == nullptr)
return; return;
// Create a macro command using beginMacro() and endMacro() // Create a macro command using beginMacro() and endMacro()
@ -427,7 +428,7 @@ void MainWindow::addSnowman()
void MainWindow::addRobot() void MainWindow::addRobot()
{ {
Document *doc = currentDocument(); Document *doc = currentDocument();
if (doc == 0) if (doc == nullptr)
return; return;
// Compose a macro command by explicitly adding children to a parent command // Compose a macro command by explicitly adding children to a parent command

View File

@ -61,7 +61,7 @@ class MainWindow : public QMainWindow, public Ui::MainWindow
Q_OBJECT Q_OBJECT
public: public:
MainWindow(QWidget *parent = 0); MainWindow(QWidget *parent = nullptr);
void addDocument(Document *doc); void addDocument(Document *doc);
void removeDocument(Document *doc); void removeDocument(Document *doc);

View File

@ -48,19 +48,17 @@
** **
****************************************************************************/ ****************************************************************************/
#include <QtWidgets>
#include "commands.h" #include "commands.h"
#include "diagramitem.h" #include "diagramitem.h"
#include <QGraphicsScene>
//! [0] //! [0]
MoveCommand::MoveCommand(DiagramItem *diagramItem, const QPointF &oldPos, MoveCommand::MoveCommand(DiagramItem *diagramItem, const QPointF &oldPos,
QUndoCommand *parent) QUndoCommand *parent)
: QUndoCommand(parent) : QUndoCommand(parent), myDiagramItem(diagramItem)
, myOldPos(oldPos), newPos(diagramItem->pos())
{ {
myDiagramItem = diagramItem;
newPos = diagramItem->pos();
myOldPos = oldPos;
} }
//! [0] //! [0]
@ -71,7 +69,7 @@ bool MoveCommand::mergeWith(const QUndoCommand *command)
DiagramItem *item = moveCommand->myDiagramItem; DiagramItem *item = moveCommand->myDiagramItem;
if (myDiagramItem != item) if (myDiagramItem != item)
return false; return false;
newPos = item->pos(); newPos = item->pos();
setText(QObject::tr("Move %1") setText(QObject::tr("Move %1")
@ -102,9 +100,8 @@ void MoveCommand::redo()
//! [4] //! [4]
DeleteCommand::DeleteCommand(QGraphicsScene *scene, QUndoCommand *parent) DeleteCommand::DeleteCommand(QGraphicsScene *scene, QUndoCommand *parent)
: QUndoCommand(parent) : QUndoCommand(parent), myGraphicsScene(scene)
{ {
myGraphicsScene = scene;
QList<QGraphicsItem *> list = myGraphicsScene->selectedItems(); QList<QGraphicsItem *> list = myGraphicsScene->selectedItems();
list.first()->setSelected(false); list.first()->setSelected(false);
myDiagramItem = static_cast<DiagramItem *>(list.first()); myDiagramItem = static_cast<DiagramItem *>(list.first());
@ -131,11 +128,10 @@ void DeleteCommand::redo()
//! [7] //! [7]
AddCommand::AddCommand(DiagramItem::DiagramType addType, AddCommand::AddCommand(DiagramItem::DiagramType addType,
QGraphicsScene *scene, QUndoCommand *parent) QGraphicsScene *scene, QUndoCommand *parent)
: QUndoCommand(parent) : QUndoCommand(parent), myGraphicsScene(scene)
{ {
static int itemCount = 0; static int itemCount = 0;
myGraphicsScene = scene;
myDiagramItem = new DiagramItem(addType); myDiagramItem = new DiagramItem(addType);
initialPosition = QPointF((itemCount * 15) % int(scene->width()), initialPosition = QPointF((itemCount * 15) % int(scene->width()),
(itemCount * 15) % int(scene->height())); (itemCount * 15) % int(scene->height()));

View File

@ -62,7 +62,7 @@ public:
enum { Id = 1234 }; enum { Id = 1234 };
MoveCommand(DiagramItem *diagramItem, const QPointF &oldPos, MoveCommand(DiagramItem *diagramItem, const QPointF &oldPos,
QUndoCommand *parent = 0); QUndoCommand *parent = nullptr);
void undo() override; void undo() override;
void redo() override; void redo() override;
@ -80,7 +80,7 @@ private:
class DeleteCommand : public QUndoCommand class DeleteCommand : public QUndoCommand
{ {
public: public:
explicit DeleteCommand(QGraphicsScene *graphicsScene, QUndoCommand *parent = 0); explicit DeleteCommand(QGraphicsScene *graphicsScene, QUndoCommand *parent = nullptr);
void undo() override; void undo() override;
void redo() override; void redo() override;
@ -96,7 +96,7 @@ class AddCommand : public QUndoCommand
{ {
public: public:
AddCommand(DiagramItem::DiagramType addType, QGraphicsScene *graphicsScene, AddCommand(DiagramItem::DiagramType addType, QGraphicsScene *graphicsScene,
QUndoCommand *parent = 0); QUndoCommand *parent = nullptr);
~AddCommand(); ~AddCommand();
void undo() override; void undo() override;

View File

@ -48,10 +48,11 @@
** **
****************************************************************************/ ****************************************************************************/
#include <QtWidgets>
#include "diagramitem.h" #include "diagramitem.h"
#include <QBrush>
#include <QRandomGenerator>
DiagramItem::DiagramItem(DiagramType diagramType, QGraphicsItem *item) DiagramItem::DiagramItem(DiagramType diagramType, QGraphicsItem *item)
: QGraphicsPolygonItem(item) : QGraphicsPolygonItem(item)
{ {
@ -65,7 +66,9 @@ DiagramItem::DiagramItem(DiagramType diagramType, QGraphicsItem *item)
setPolygon(trianglePolygon); setPolygon(trianglePolygon);
} }
QColor color(QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256)); QColor color(QRandomGenerator::global()->bounded(256),
QRandomGenerator::global()->bounded(256),
QRandomGenerator::global()->bounded(256));
QBrush brush(color); QBrush brush(color);
setBrush(brush); setBrush(brush);
setFlag(QGraphicsItem::ItemIsSelectable); setFlag(QGraphicsItem::ItemIsSelectable);

View File

@ -66,9 +66,10 @@ public:
enum { Type = UserType + 1 }; enum { Type = UserType + 1 };
enum DiagramType { Box, Triangle }; enum DiagramType { Box, Triangle };
explicit DiagramItem(DiagramType diagramType, QGraphicsItem *item = 0); explicit DiagramItem(DiagramType diagramType, QGraphicsItem *item = nullptr);
DiagramType diagramType() const { DiagramType diagramType() const
{
return polygon() == boxPolygon ? Box : Triangle; return polygon() == boxPolygon ? Box : Triangle;
} }
int type() const override { return Type; } int type() const override { return Type; }

View File

@ -48,27 +48,24 @@
** **
****************************************************************************/ ****************************************************************************/
#include <QtWidgets>
#include "diagramscene.h" #include "diagramscene.h"
#include "diagramitem.h" #include "diagramitem.h"
#include <QGraphicsSceneMouseEvent>
DiagramScene::DiagramScene(QObject *parent) DiagramScene::DiagramScene(QObject *parent)
: QGraphicsScene(parent) : QGraphicsScene(parent)
{ {}
movingItem = 0;
}
void DiagramScene::mousePressEvent(QGraphicsSceneMouseEvent *event) void DiagramScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
{ {
QPointF mousePos(event->buttonDownScenePos(Qt::LeftButton).x(), QPointF mousePos(event->buttonDownScenePos(Qt::LeftButton).x(),
event->buttonDownScenePos(Qt::LeftButton).y()); event->buttonDownScenePos(Qt::LeftButton).y());
const QList<QGraphicsItem *> itemList = items(mousePos); const QList<QGraphicsItem *> itemList = items(mousePos);
movingItem = itemList.isEmpty() ? 0 : itemList.first(); movingItem = itemList.isEmpty() ? nullptr : itemList.first();
if (movingItem != 0 && event->button() == Qt::LeftButton) { if (movingItem != nullptr && event->button() == Qt::LeftButton)
oldPos = movingItem->pos(); oldPos = movingItem->pos();
}
clearSelection(); clearSelection();
QGraphicsScene::mousePressEvent(event); QGraphicsScene::mousePressEvent(event);
@ -76,11 +73,11 @@ void DiagramScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
void DiagramScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) void DiagramScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{ {
if (movingItem != 0 && event->button() == Qt::LeftButton) { if (movingItem != nullptr && event->button() == Qt::LeftButton) {
if (oldPos != movingItem->pos()) if (oldPos != movingItem->pos())
emit itemMoved(qgraphicsitem_cast<DiagramItem *>(movingItem), emit itemMoved(qgraphicsitem_cast<DiagramItem *>(movingItem),
oldPos); oldPos);
movingItem = 0; movingItem = nullptr;
} }
QGraphicsScene::mouseReleaseEvent(event); QGraphicsScene::mouseReleaseEvent(event);
} }

View File

@ -66,7 +66,7 @@ class DiagramScene : public QGraphicsScene
Q_OBJECT Q_OBJECT
public: public:
DiagramScene(QObject *parent = 0); DiagramScene(QObject *parent = nullptr);
signals: signals:
void itemMoved(DiagramItem *movedItem, const QPointF &movedFromPosition); void itemMoved(DiagramItem *movedItem, const QPointF &movedFromPosition);
@ -76,7 +76,7 @@ protected:
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override; void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
private: private:
QGraphicsItem *movingItem; QGraphicsItem *movingItem = nullptr;
QPointF oldPos; QPointF oldPos;
}; };
//! [0] //! [0]

View File

@ -48,7 +48,7 @@
** **
****************************************************************************/ ****************************************************************************/
#include <QtWidgets> #include <QApplication>
#include "mainwindow.h" #include "mainwindow.h"

View File

@ -48,13 +48,18 @@
** **
****************************************************************************/ ****************************************************************************/
#include <QtWidgets>
#include "mainwindow.h" #include "mainwindow.h"
#include "diagramscene.h" #include "diagramscene.h"
#include "diagramitem.h" #include "diagramitem.h"
#include "commands.h" #include "commands.h"
#include <QAction>
#include <QGraphicsView>
#include <QMenu>
#include <QMenuBar>
#include <QMessageBox>
#include <QUndoView>
//! [0] //! [0]
MainWindow::MainWindow() MainWindow::MainWindow()
{ {

View File

@ -87,22 +87,22 @@ private:
void createMenus(); void createMenus();
void createUndoView(); void createUndoView();
QAction *deleteAction; QAction *deleteAction = nullptr;
QAction *addBoxAction; QAction *addBoxAction = nullptr;
QAction *addTriangleAction; QAction *addTriangleAction = nullptr;
QAction *undoAction; QAction *undoAction = nullptr;
QAction *redoAction; QAction *redoAction = nullptr;
QAction *exitAction; QAction *exitAction = nullptr;
QAction *aboutAction; QAction *aboutAction = nullptr;
QMenu *fileMenu; QMenu *fileMenu = nullptr;
QMenu *editMenu; QMenu *editMenu = nullptr;
QMenu *itemMenu; QMenu *itemMenu = nullptr;
QMenu *helpMenu; QMenu *helpMenu = nullptr;
DiagramScene *diagramScene; DiagramScene *diagramScene = nullptr;
QUndoStack *undoStack; QUndoStack *undoStack = nullptr;
QUndoView *undoView; QUndoView *undoView = nullptr;
}; };
//! [0] //! [0]

View File

@ -14,7 +14,6 @@ include(unix.conf)
QMAKE_RESOURCE = /Developer/Tools/Rez QMAKE_RESOURCE = /Developer/Tools/Rez
QMAKE_EXTENSION_SHLIB = dylib QMAKE_EXTENSION_SHLIB = dylib
QMAKE_EXTENSIONS_AUX_SHLIB = tbd
QMAKE_LIBDIR = QMAKE_LIBDIR =
# sdk.prf will prefix the proper SDK sysroot # sdk.prf will prefix the proper SDK sysroot

View File

@ -300,7 +300,8 @@ mac {
CMAKE_PRL_FILE_LOCATION_RELEASE = lib$${CMAKE_QT_STEM}.prl CMAKE_PRL_FILE_LOCATION_RELEASE = lib$${CMAKE_QT_STEM}.prl
} else { } else {
qt_framework { qt_framework {
CMAKE_LIB_FILE_LOCATION_DEBUG = $${CMAKE_QT_STEM}.framework/$${CMAKE_QT_STEM}_debug # Intentionally there is no '_debug' infix for framework builds.
CMAKE_LIB_FILE_LOCATION_DEBUG = $${CMAKE_QT_STEM}.framework/$${CMAKE_QT_STEM}
CMAKE_LIB_FILE_LOCATION_RELEASE = $${CMAKE_QT_STEM}.framework/$${CMAKE_QT_STEM} CMAKE_LIB_FILE_LOCATION_RELEASE = $${CMAKE_QT_STEM}.framework/$${CMAKE_QT_STEM}
CMAKE_BUILD_IS_FRAMEWORK = "true" CMAKE_BUILD_IS_FRAMEWORK = "true"
} else { } else {

View File

@ -22,6 +22,8 @@ for(ever) {
!defined(QMAKE_LIBS_$$nu, var): \ !defined(QMAKE_LIBS_$$nu, var): \
error("Library '$$lower($$replace(nu, _, -))' is not defined.") error("Library '$$lower($$replace(nu, _, -))' is not defined.")
QMAKE_LIBDIR += $$eval(QMAKE_LIBDIR_$$nu)
android { android {
ABI_LIBS = $$eval(QMAKE_LIBS_$${nu}_$${QT_ARCH}) ABI_LIBS = $$eval(QMAKE_LIBS_$${nu}_$${QT_ARCH})
isEmpty(ABI_LIBS): ABI_LIBS = $$eval(QMAKE_LIBS_$${nu}) isEmpty(ABI_LIBS): ABI_LIBS = $$eval(QMAKE_LIBS_$${nu})

View File

@ -537,98 +537,23 @@ defineReplace(qtGccSysrootifiedPaths) {
return($$sysrootified) return($$sysrootified)
} }
# libs-var, libs, in-paths, out-paths-var # libs-var, libs, in-paths
defineTest(qtConfResolveLibs) { defineTest(qtConfResolveLibs) {
ret = true for (path, 3): \
paths = $$3 pre_lflags += -L$$path
out = $$1 = $$pre_lflags $$2
copy = false
for (l, 2) {
$$copy {
copy = false
out += $$l
} else: equals(l, "-s") {
# em++ flag to link libraries from emscripten-ports; passed on literally.
copy = true
out += $$l
} else: contains(l, "^-L.*") {
lp = $$replace(l, "^-L", )
gcc: lp = $$qtGccSysrootifiedPath($$lp)
!exists($$lp/.) {
qtLog("Library path $$val_escape(lp) is invalid.")
ret = false
} else {
paths += $$lp
}
} else: !android: contains(l, "^-l.*") {
lib = $$replace(l, "^-l", )
lcan =
integrity:contains(lib, "^.*\\.a") {
# INTEGRITY compiler searches for exact filename
# if -l argument has .a suffix
lcan += $${lib}
} else: contains(lib, "^:.*") {
# Use exact filename when -l:filename syntax is used.
lib ~= s/^://
lcan += $${lib}
} else: unix {
# Under UNIX, we look for actual shared libraries, in addition
# to static ones.
shexts = $$QMAKE_EXTENSION_SHLIB $$QMAKE_EXTENSIONS_AUX_SHLIB
for (ext, shexts) {
lcan += $${QMAKE_PREFIX_SHLIB}$${lib}.$${ext}
}
lcan += \
$${QMAKE_PREFIX_STATICLIB}$${lib}.$${QMAKE_EXTENSION_STATICLIB}
} else {
# Under Windows, we look only for static libraries, as even for DLLs
# one actually links against a static import library.
mingw {
lcan += \
# MinGW supports UNIX-style library naming in addition to
# the MSVC style.
lib$${lib}.dll.a lib$${lib}.a \
# Fun fact: prefix-less libraries are also supported.
$${lib}.dll.a $${lib}.a
}
lcan += $${lib}.lib
}
l = $$qtConfFindInPathList($$lcan, $$paths $$EXTRA_LIBDIR $$QMAKE_DEFAULT_LIBDIRS)
isEmpty(l) {
qtLog("None of [$$val_escape(lcan)] found in [$$val_escape(paths)] and global paths.")
ret = false
} else {
out += $$l
}
} else {
out += $$l
}
}
$$1 = $$out
export($$1) export($$1)
!isEmpty(4) { return(true)
$$4 = $$paths
export($$4)
}
return($$ret)
}
# source-var
defineTest(qtConfResolveAllLibs) {
ret = true
!qtConfResolveLibs($${1}.libs, $$eval($${1}.libs), , $${1}.libdirs): \
ret = false
for (b, $${1}.builds._KEYS_): \
!qtConfResolveLibs($${1}.builds.$${b}, $$eval($${1}.builds.$${b}), $$eval($${1}.libdirs), ): \
ret = false
return($$ret)
} }
# libs-var, in-paths, libs # libs-var, in-paths, libs
defineTest(qtConfResolvePathLibs) { defineTest(qtConfResolvePathLibs) {
ret = true ret = true
gcc: 2 = $$qtGccSysrootifiedPaths($$2) gcc: \
for (libdir, 2) { local_paths = $$qtGccSysrootifiedPaths($$2)
else: \
local_paths = $$2
for (libdir, local_paths) {
!exists($$libdir/.) { !exists($$libdir/.) {
qtLog("Library path $$val_escape(libdir) is invalid.") qtLog("Library path $$val_escape(libdir) is invalid.")
ret = false ret = false
@ -678,8 +603,11 @@ defineReplace(qtConfGetTestIncludes) {
# includes-var, in-paths, test-object-var # includes-var, in-paths, test-object-var
defineTest(qtConfResolvePathIncs) { defineTest(qtConfResolvePathIncs) {
ret = true ret = true
gcc: 2 = $$qtGccSysrootifiedPaths($$2) gcc: \
for (incdir, 2) { local_paths = $$qtGccSysrootifiedPaths($$2)
else: \
local_paths = $$2
for (incdir, local_paths) {
!exists($$incdir/.) { !exists($$incdir/.) {
qtLog("Include path $$val_escape(incdir) is invalid.") qtLog("Include path $$val_escape(incdir) is invalid.")
ret = false ret = false
@ -773,11 +701,9 @@ defineTest(qtConfLibrary_inline) {
for (ld, libdir): \ for (ld, libdir): \
libs += -L$$ld libs += -L$$ld
$${1}.libs = $$libs $$eval($${1}.libs) $${1}.libs = $$libs $$eval($${1}.libs)
export($${1}.libs)
} }
!qtConfResolveAllLibs($$1): \
return(false)
!qtConfResolvePathIncs($${1}.includedir, $$includes, $$2): \ !qtConfResolvePathIncs($${1}.includedir, $$includes, $$2): \
return(false) return(false)

View File

@ -56,13 +56,13 @@ int main(int argc, char *argv[])
QTranslator translator; QTranslator translator;
// look up e.g. :/translations/myapp_de.qm // look up e.g. :/translations/myapp_de.qm
if (translator.load(QLocale(), QLatin1String("myapp"), QLatin1String("_"), QLatin1String(":/translations"))) if (translator.load(QLocale(), QLatin1String("myapp"), QLatin1String("_"), QLatin1String(":/translations")))
app.installTranslator(&translator); QCoreApplication::installTranslator(&translator);
QPushButton hello(QCoreApplication::translate("main", "Hello world!")); QPushButton hello(QCoreApplication::translate("main", "Hello world!"));
hello.resize(100, 30); hello.resize(100, 30);
hello.show(); hello.show();
return app.exec(); return QCoreApplication::exec();
} }
//! [0] //! [0]

View File

@ -41,9 +41,9 @@
#include "qfilesystemwatcher_p.h" #include "qfilesystemwatcher_p.h"
#include <qdatetime.h> #include <qdatetime.h>
#include <qdebug.h>
#include <qdir.h> #include <qdir.h>
#include <qfileinfo.h> #include <qfileinfo.h>
#include <qloggingcategory.h>
#include <qset.h> #include <qset.h>
#include <qtimer.h> #include <qtimer.h>
@ -67,6 +67,8 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcWatcher, "qt.core.filesystemwatcher")
QFileSystemWatcherEngine *QFileSystemWatcherPrivate::createNativeEngine(QObject *parent) QFileSystemWatcherEngine *QFileSystemWatcherPrivate::createNativeEngine(QObject *parent)
{ {
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
@ -137,6 +139,7 @@ void QFileSystemWatcherPrivate::initPollerEngine()
void QFileSystemWatcherPrivate::_q_fileChanged(const QString &path, bool removed) void QFileSystemWatcherPrivate::_q_fileChanged(const QString &path, bool removed)
{ {
Q_Q(QFileSystemWatcher); Q_Q(QFileSystemWatcher);
qCDebug(lcWatcher) << "file changed" << path << "removed?" << removed << "watching?" << files.contains(path);
if (!files.contains(path)) { if (!files.contains(path)) {
// the path was removed after a change was detected, but before we delivered the signal // the path was removed after a change was detected, but before we delivered the signal
return; return;
@ -149,6 +152,7 @@ void QFileSystemWatcherPrivate::_q_fileChanged(const QString &path, bool removed
void QFileSystemWatcherPrivate::_q_directoryChanged(const QString &path, bool removed) void QFileSystemWatcherPrivate::_q_directoryChanged(const QString &path, bool removed)
{ {
Q_Q(QFileSystemWatcher); Q_Q(QFileSystemWatcher);
qCDebug(lcWatcher) << "directory changed" << path << "removed?" << removed << "watching?" << directories.contains(path);
if (!directories.contains(path)) { if (!directories.contains(path)) {
// perhaps the path was removed after a change was detected, but before we delivered the signal // perhaps the path was removed after a change was detected, but before we delivered the signal
return; return;
@ -355,7 +359,7 @@ QStringList QFileSystemWatcher::addPaths(const QStringList &paths)
qWarning("QFileSystemWatcher::addPaths: list is empty"); qWarning("QFileSystemWatcher::addPaths: list is empty");
return p; return p;
} }
qCDebug(lcWatcher) << "adding" << paths;
const auto selectEngine = [this, d]() -> QFileSystemWatcherEngine* { const auto selectEngine = [this, d]() -> QFileSystemWatcherEngine* {
#ifdef QT_BUILD_INTERNAL #ifdef QT_BUILD_INTERNAL
const QString on = objectName(); const QString on = objectName();
@ -364,11 +368,11 @@ QStringList QFileSystemWatcher::addPaths(const QStringList &paths)
// Autotest override case - use the explicitly selected engine only // Autotest override case - use the explicitly selected engine only
const QStringRef forceName = on.midRef(26); const QStringRef forceName = on.midRef(26);
if (forceName == QLatin1String("poller")) { if (forceName == QLatin1String("poller")) {
qDebug("QFileSystemWatcher: skipping native engine, using only polling engine"); qCDebug(lcWatcher, "QFileSystemWatcher: skipping native engine, using only polling engine");
d_func()->initPollerEngine(); d_func()->initPollerEngine();
return d->poller; return d->poller;
} else if (forceName == QLatin1String("native")) { } else if (forceName == QLatin1String("native")) {
qDebug("QFileSystemWatcher: skipping polling engine, using only native engine"); qCDebug(lcWatcher, "QFileSystemWatcher: skipping polling engine, using only native engine");
return d->native; return d->native;
} }
return nullptr; return nullptr;
@ -431,6 +435,7 @@ QStringList QFileSystemWatcher::removePaths(const QStringList &paths)
qWarning("QFileSystemWatcher::removePaths: list is empty"); qWarning("QFileSystemWatcher::removePaths: list is empty");
return p; return p;
} }
qCDebug(lcWatcher) << "removing" << paths;
if (d->native) if (d->native)
p = d->native->removePaths(p, &d->files, &d->directories); p = d->native->removePaths(p, &d->files, &d->directories);

View File

@ -2693,7 +2693,14 @@ Q_GLOBAL_STATIC(QRecursiveMutex, libraryPathMutex)
QStringList QCoreApplication::libraryPaths() QStringList QCoreApplication::libraryPaths()
{ {
QMutexLocker locker(libraryPathMutex()); QMutexLocker locker(libraryPathMutex());
return libraryPathsLocked();
}
/*!
\internal
*/
QStringList QCoreApplication::libraryPathsLocked()
{
if (coreappdata()->manual_libpaths) if (coreappdata()->manual_libpaths)
return *(coreappdata()->manual_libpaths); return *(coreappdata()->manual_libpaths);
@ -2769,7 +2776,7 @@ void QCoreApplication::setLibraryPaths(const QStringList &paths)
// When the application is constructed it should still amend the paths. So we keep the originals // When the application is constructed it should still amend the paths. So we keep the originals
// around, and even create them if they don't exist, yet. // around, and even create them if they don't exist, yet.
if (!coreappdata()->app_libpaths) if (!coreappdata()->app_libpaths)
libraryPaths(); libraryPathsLocked();
if (coreappdata()->manual_libpaths) if (coreappdata()->manual_libpaths)
*(coreappdata()->manual_libpaths) = paths; *(coreappdata()->manual_libpaths) = paths;
@ -2812,7 +2819,7 @@ void QCoreApplication::addLibraryPath(const QString &path)
return; return;
} else { } else {
// make sure that library paths are initialized // make sure that library paths are initialized
libraryPaths(); libraryPathsLocked();
QStringList *app_libpaths = coreappdata()->app_libpaths.data(); QStringList *app_libpaths = coreappdata()->app_libpaths.data();
if (app_libpaths->contains(canonicalPath)) if (app_libpaths->contains(canonicalPath))
return; return;
@ -2851,7 +2858,7 @@ void QCoreApplication::removeLibraryPath(const QString &path)
return; return;
} else { } else {
// make sure that library paths is initialized // make sure that library paths is initialized
libraryPaths(); libraryPathsLocked();
QStringList *app_libpaths = coreappdata()->app_libpaths.data(); QStringList *app_libpaths = coreappdata()->app_libpaths.data();
if (!app_libpaths->contains(canonicalPath)) if (!app_libpaths->contains(canonicalPath))
return; return;

View File

@ -208,6 +208,9 @@ private:
static bool notifyInternal2(QObject *receiver, QEvent *); static bool notifyInternal2(QObject *receiver, QEvent *);
static bool forwardEvent(QObject *receiver, QEvent *event, QEvent *originatingEvent = nullptr); static bool forwardEvent(QObject *receiver, QEvent *event, QEvent *originatingEvent = nullptr);
#endif #endif
#if QT_CONFIG(library)
static QStringList libraryPathsLocked();
#endif
static QCoreApplication *self; static QCoreApplication *self;

View File

@ -54,20 +54,11 @@ class QPointer
{ {
Q_STATIC_ASSERT_X(!std::is_pointer<T>::value, "QPointer's template type must not be a pointer type"); Q_STATIC_ASSERT_X(!std::is_pointer<T>::value, "QPointer's template type must not be a pointer type");
template<typename U> using QObjectType =
struct TypeSelector typename std::conditional<std::is_const<T>::value, const QObject, QObject>::type;
{
typedef QObject Type;
};
template<typename U>
struct TypeSelector<const U>
{
typedef const QObject Type;
};
typedef typename TypeSelector<T>::Type QObjectType;
QWeakPointer<QObjectType> wp; QWeakPointer<QObjectType> wp;
public: public:
inline QPointer() { } QPointer() = default;
inline QPointer(T *p) : wp(p, true) { } inline QPointer(T *p) : wp(p, true) { }
// compiler-generated copy/move ctor/assignment operators are fine! // compiler-generated copy/move ctor/assignment operators are fine!
// compiler-generated dtor is fine! // compiler-generated dtor is fine!

View File

@ -48,6 +48,9 @@
#include "qreadwritelock_p.h" #include "qreadwritelock_p.h"
#include "qelapsedtimer.h" #include "qelapsedtimer.h"
#include "private/qfreelist_p.h" #include "private/qfreelist_p.h"
#include "private/qlocking_p.h"
#include <chrono>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -64,6 +67,9 @@ QT_BEGIN_NAMESPACE
*/ */
namespace { namespace {
using ms = std::chrono::milliseconds;
enum { enum {
StateMask = 0x3, StateMask = 0x3,
StateLockedForRead = 0x1, StateLockedForRead = 0x1,
@ -262,7 +268,7 @@ bool QReadWriteLock::tryLockForRead(int timeout)
if (d->recursive) if (d->recursive)
return d->recursiveLockForRead(timeout); return d->recursiveLockForRead(timeout);
QMutexLocker lock(&d->mutex); auto lock = qt_unique_lock(d->mutex);
if (d != d_ptr.loadRelaxed()) { if (d != d_ptr.loadRelaxed()) {
// d_ptr has changed: this QReadWriteLock was unlocked before we had // d_ptr has changed: this QReadWriteLock was unlocked before we had
// time to lock d->mutex. // time to lock d->mutex.
@ -273,7 +279,7 @@ bool QReadWriteLock::tryLockForRead(int timeout)
d = d_ptr.loadAcquire(); d = d_ptr.loadAcquire();
continue; continue;
} }
return d->lockForRead(timeout); return d->lockForRead(lock, timeout);
} }
} }
@ -369,7 +375,7 @@ bool QReadWriteLock::tryLockForWrite(int timeout)
if (d->recursive) if (d->recursive)
return d->recursiveLockForWrite(timeout); return d->recursiveLockForWrite(timeout);
QMutexLocker lock(&d->mutex); auto lock = qt_unique_lock(d->mutex);
if (d != d_ptr.loadRelaxed()) { if (d != d_ptr.loadRelaxed()) {
// The mutex was unlocked before we had time to lock the mutex. // The mutex was unlocked before we had time to lock the mutex.
// We are holding to a mutex within a QReadWriteLockPrivate that is already released // We are holding to a mutex within a QReadWriteLockPrivate that is already released
@ -377,7 +383,7 @@ bool QReadWriteLock::tryLockForWrite(int timeout)
d = d_ptr.loadAcquire(); d = d_ptr.loadAcquire();
continue; continue;
} }
return d->lockForWrite(timeout); return d->lockForWrite(lock, timeout);
} }
} }
@ -418,7 +424,7 @@ void QReadWriteLock::unlock()
return; return;
} }
QMutexLocker locker(&d->mutex); const auto lock = qt_scoped_lock(d->mutex);
if (d->writerCount) { if (d->writerCount) {
Q_ASSERT(d->writerCount == 1); Q_ASSERT(d->writerCount == 1);
Q_ASSERT(d->readerCount == 0); Q_ASSERT(d->readerCount == 0);
@ -460,9 +466,9 @@ QReadWriteLock::StateForWaitCondition QReadWriteLock::stateForWaitCondition() co
} }
bool QReadWriteLockPrivate::lockForRead(int timeout) bool QReadWriteLockPrivate::lockForRead(std::unique_lock<std::mutex> &lock, int timeout)
{ {
Q_ASSERT(!mutex.tryLock()); // mutex must be locked when entering this function Q_ASSERT(!mutex.try_lock()); // mutex must be locked when entering this function
QElapsedTimer t; QElapsedTimer t;
if (timeout > 0) if (timeout > 0)
@ -476,10 +482,10 @@ bool QReadWriteLockPrivate::lockForRead(int timeout)
if (elapsed > timeout) if (elapsed > timeout)
return false; return false;
waitingReaders++; waitingReaders++;
readerCond.wait(&mutex, timeout - elapsed); readerCond.wait_for(lock, ms{timeout - elapsed});
} else { } else {
waitingReaders++; waitingReaders++;
readerCond.wait(&mutex); readerCond.wait(lock);
} }
waitingReaders--; waitingReaders--;
} }
@ -488,9 +494,9 @@ bool QReadWriteLockPrivate::lockForRead(int timeout)
return true; return true;
} }
bool QReadWriteLockPrivate::lockForWrite(int timeout) bool QReadWriteLockPrivate::lockForWrite(std::unique_lock<std::mutex> &lock, int timeout)
{ {
Q_ASSERT(!mutex.tryLock()); // mutex must be locked when entering this function Q_ASSERT(!mutex.try_lock()); // mutex must be locked when entering this function
QElapsedTimer t; QElapsedTimer t;
if (timeout > 0) if (timeout > 0)
@ -505,15 +511,15 @@ bool QReadWriteLockPrivate::lockForWrite(int timeout)
if (waitingReaders && !waitingWriters && !writerCount) { if (waitingReaders && !waitingWriters && !writerCount) {
// We timed out and now there is no more writers or waiting writers, but some // We timed out and now there is no more writers or waiting writers, but some
// readers were queueud (probably because of us). Wake the waiting readers. // readers were queueud (probably because of us). Wake the waiting readers.
readerCond.wakeAll(); readerCond.notify_all();
} }
return false; return false;
} }
waitingWriters++; waitingWriters++;
writerCond.wait(&mutex, timeout - elapsed); writerCond.wait_for(lock, ms{timeout - elapsed});
} else { } else {
waitingWriters++; waitingWriters++;
writerCond.wait(&mutex); writerCond.wait(lock);
} }
waitingWriters--; waitingWriters--;
} }
@ -526,17 +532,17 @@ bool QReadWriteLockPrivate::lockForWrite(int timeout)
void QReadWriteLockPrivate::unlock() void QReadWriteLockPrivate::unlock()
{ {
Q_ASSERT(!mutex.tryLock()); // mutex must be locked when entering this function Q_ASSERT(!mutex.try_lock()); // mutex must be locked when entering this function
if (waitingWriters) if (waitingWriters)
writerCond.wakeOne(); writerCond.notify_one();
else if (waitingReaders) else if (waitingReaders)
readerCond.wakeAll(); readerCond.notify_all();
} }
bool QReadWriteLockPrivate::recursiveLockForRead(int timeout) bool QReadWriteLockPrivate::recursiveLockForRead(int timeout)
{ {
Q_ASSERT(recursive); Q_ASSERT(recursive);
QMutexLocker lock(&mutex); auto lock = qt_unique_lock(mutex);
Qt::HANDLE self = QThread::currentThreadId(); Qt::HANDLE self = QThread::currentThreadId();
@ -546,7 +552,7 @@ bool QReadWriteLockPrivate::recursiveLockForRead(int timeout)
return true; return true;
} }
if (!lockForRead(timeout)) if (!lockForRead(lock, timeout))
return false; return false;
currentReaders.insert(self, 1); currentReaders.insert(self, 1);
@ -556,7 +562,7 @@ bool QReadWriteLockPrivate::recursiveLockForRead(int timeout)
bool QReadWriteLockPrivate::recursiveLockForWrite(int timeout) bool QReadWriteLockPrivate::recursiveLockForWrite(int timeout)
{ {
Q_ASSERT(recursive); Q_ASSERT(recursive);
QMutexLocker lock(&mutex); auto lock = qt_unique_lock(mutex);
Qt::HANDLE self = QThread::currentThreadId(); Qt::HANDLE self = QThread::currentThreadId();
if (currentWriter == self) { if (currentWriter == self) {
@ -564,7 +570,7 @@ bool QReadWriteLockPrivate::recursiveLockForWrite(int timeout)
return true; return true;
} }
if (!lockForWrite(timeout)) if (!lockForWrite(lock, timeout))
return false; return false;
currentWriter = self; currentWriter = self;
@ -574,7 +580,7 @@ bool QReadWriteLockPrivate::recursiveLockForWrite(int timeout)
void QReadWriteLockPrivate::recursiveUnlock() void QReadWriteLockPrivate::recursiveUnlock()
{ {
Q_ASSERT(recursive); Q_ASSERT(recursive);
QMutexLocker lock(&mutex); auto lock = qt_unique_lock(mutex);
Qt::HANDLE self = QThread::currentThreadId(); Qt::HANDLE self = QThread::currentThreadId();
if (self == currentWriter) { if (self == currentWriter) {

View File

@ -54,7 +54,9 @@
#include <QtCore/private/qglobal_p.h> #include <QtCore/private/qglobal_p.h>
#include <QtCore/qhash.h> #include <QtCore/qhash.h>
#include <QtCore/qwaitcondition.h>
#include <mutex>
#include <condition_variable>
QT_REQUIRE_CONFIG(thread); QT_REQUIRE_CONFIG(thread);
@ -63,38 +65,36 @@ QT_BEGIN_NAMESPACE
class QReadWriteLockPrivate class QReadWriteLockPrivate
{ {
public: public:
QReadWriteLockPrivate(bool isRecursive = false) explicit QReadWriteLockPrivate(bool isRecursive = false)
: readerCount(0), writerCount(0), waitingReaders(0), waitingWriters(0), : recursive(isRecursive) {}
recursive(isRecursive), id(0), currentWriter(nullptr) {}
QMutex mutex; std::mutex mutex;
QWaitCondition writerCond; std::condition_variable writerCond;
QWaitCondition readerCond; std::condition_variable readerCond;
int readerCount; int readerCount = 0;
int writerCount; int writerCount = 0;
int waitingReaders; int waitingReaders = 0;
int waitingWriters; int waitingWriters = 0;
const bool recursive; const bool recursive;
//Called with the mutex locked //Called with the mutex locked
bool lockForWrite(int timeout); bool lockForWrite(std::unique_lock<std::mutex> &lock, int timeout);
bool lockForRead(int timeout); bool lockForRead(std::unique_lock<std::mutex> &lock, int timeout);
void unlock(); void unlock();
//memory management //memory management
int id; int id = 0;
void release(); void release();
static QReadWriteLockPrivate *allocate(); static QReadWriteLockPrivate *allocate();
// Recusive mutex handling // Recusive mutex handling
Qt::HANDLE currentWriter; Qt::HANDLE currentWriter = {};
QHash<Qt::HANDLE, int> currentReaders; QHash<Qt::HANDLE, int> currentReaders;
// called with the mutex unlocked // called with the mutex unlocked
bool recursiveLockForWrite(int timeout); bool recursiveLockForWrite(int timeout);
bool recursiveLockForRead(int timeout); bool recursiveLockForRead(int timeout);
void recursiveUnlock(); void recursiveUnlock();
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -3432,15 +3432,15 @@ inline qint64 QDateTimePrivate::zoneMSecsToEpochMSecs(qint64 zoneMSecs, const QT
datetime by adding a number of seconds, days, months, or years. datetime by adding a number of seconds, days, months, or years.
QDateTime can describe datetimes with respect to \l{Qt::LocalTime}{local QDateTime can describe datetimes with respect to \l{Qt::LocalTime}{local
time}, to \l{Qt::UTC}{UTC}, to a specified \l{Qt::OffsetFromUTC}{offset time}, to \l{Qt::UTC}{UTC}, to a specified \l{Qt::OffsetFromUTC}{offset from
from UTC} or to a specified \l{Qt::TimeZone}{time zone}, in conjunction UTC} or to a specified \l{Qt::TimeZone}{time zone}, in conjunction with the
with the QTimeZone class. For example, a time zone of "Europe/Berlin" will QTimeZone class. For example, a time zone of "Europe/Berlin" will apply the
apply the daylight-saving rules as used in Germany since 1970. In contrast, daylight-saving rules as used in Germany since 1970. In contrast, an offset
an offset from UTC of +3600 seconds is one hour ahead of UTC (usually from UTC of +3600 seconds is one hour ahead of UTC (usually written in ISO
written in ISO standard notation as "UTC+01:00"), with no daylight-saving standard notation as "UTC+01:00"), with no daylight-saving offset or
offset or changes. When using either local time or a specified time zone, changes. When using either local time or a specified time zone, time-zone
time-zone transitions such as the starts and ends of daylight-saving time transitions such as the starts and ends of daylight-saving time (DST; but
(DST) are taken into account. The choice of system used to represent a see below) are taken into account. The choice of system used to represent a
datetime is described as its "timespec". datetime is described as its "timespec".
A QDateTime object is typically created either by giving a date and time A QDateTime object is typically created either by giving a date and time
@ -3528,11 +3528,13 @@ inline qint64 QDateTimePrivate::zoneMSecsToEpochMSecs(qint64 zoneMSecs, const QT
The range of valid dates taking DST into account is 1970-01-01 to the The range of valid dates taking DST into account is 1970-01-01 to the
present, and rules are in place for handling DST correctly until 2037-12-31, present, and rules are in place for handling DST correctly until 2037-12-31,
but these could change. For dates falling outside that range, QDateTime but these could change. For dates after 2037, QDateTime makes a \e{best
makes a \e{best guess} using the rules for year 1970 or 2037, but we can't guess} using the rules for year 2037, but we can't guarantee accuracy;
guarantee accuracy. This means QDateTime doesn't take into account changes indeed, for \e{any} future date, the time-zone may change its rules before
in a time zone before 1970, even if the system's time zone database provides that date comes around. For dates before 1970, QDateTime doesn't take DST
that information. changes into account, even if the system's time zone database provides that
information, although it does take into account changes to the time-zone's
standard offset, where this information is available.
\section2 Offsets From UTC \section2 Offsets From UTC
@ -3797,17 +3799,22 @@ QTimeZone QDateTime::timeZone() const
/*! /*!
\since 5.2 \since 5.2
Returns the current Offset From UTC in seconds. Returns this date-time's Offset From UTC in seconds.
If the timeSpec() is Qt::OffsetFromUTC this will be the value originally set. The result depends on timeSpec():
\list
\li \c Qt::UTC The offset is 0.
\li \c Qt::OffsetFromUTC The offset is the value originally set.
\li \c Qt::LocalTime The local time's offset from UTC is returned.
\li \c Qt::TimeZone The offset used by the time-zone is returned.
\endlist
If the timeSpec() is Qt::TimeZone this will be the offset effective in the For the last two, the offset at this date and time will be returned, taking
Time Zone including any Daylight-Saving Offset. account of Daylight-Saving Offset unless the date precedes the start of
1970. The offset is the difference between the local time or time in the
If the timeSpec() is Qt::LocalTime this will be the difference between the given time-zone and UTC time; it is positive in time-zones ahead of UTC
Local Time and UTC including any Daylight-Saving Offset. (East of The Prime Meridian), negative for those behind UTC (West of The
Prime Meridian).
If the timeSpec() is Qt::UTC this will be 0.
\sa setOffsetFromUtc() \sa setOffsetFromUtc()
*/ */

View File

@ -371,6 +371,7 @@ QDate calculateTransitionLocalDate(const SYSTEMTIME &rule, int year)
// Otherwise, the rule date is annual and relative: // Otherwise, the rule date is annual and relative:
const int dayOfWeek = rule.wDayOfWeek == 0 ? 7 : rule.wDayOfWeek; const int dayOfWeek = rule.wDayOfWeek == 0 ? 7 : rule.wDayOfWeek;
QDate date(year, rule.wMonth, 1); QDate date(year, rule.wMonth, 1);
Q_ASSERT(date.isValid());
// How many days before was last dayOfWeek before target month ? // How many days before was last dayOfWeek before target month ?
int adjust = dayOfWeek - date.dayOfWeek(); // -6 <= adjust < 7 int adjust = dayOfWeek - date.dayOfWeek(); // -6 <= adjust < 7
if (adjust >= 0) // Ensure -7 <= adjust < 0: if (adjust >= 0) // Ensure -7 <= adjust < 0:
@ -401,6 +402,7 @@ qint64 calculateTransitionForYear(const SYSTEMTIME &rule, int year, int bias)
{ {
// TODO Consider caching the calculated values - i.e. replace SYSTEMTIME in // TODO Consider caching the calculated values - i.e. replace SYSTEMTIME in
// WinTransitionRule; do this in init() once and store the results. // WinTransitionRule; do this in init() once and store the results.
Q_ASSERT(year);
const QDate date = calculateTransitionLocalDate(rule, year); const QDate date = calculateTransitionLocalDate(rule, year);
const QTime time = QTime(rule.wHour, rule.wMinute, rule.wSecond); const QTime time = QTime(rule.wHour, rule.wMinute, rule.wSecond);
if (date.isValid() && time.isValid()) if (date.isValid() && time.isValid())
@ -479,6 +481,7 @@ struct TransitionTimePair
int yearEndOffset(const QWinTimeZonePrivate::QWinTransitionRule &rule, int year) int yearEndOffset(const QWinTimeZonePrivate::QWinTransitionRule &rule, int year)
{ {
Q_ASSERT(year);
int offset = rule.standardTimeBias; int offset = rule.standardTimeBias;
// Only needed to help another TransitionTimePair work out year + 1's start // Only needed to help another TransitionTimePair work out year + 1's start
// offset; and the oldYearOffset we use only affects an alleged transition // offset; and the oldYearOffset we use only affects an alleged transition
@ -743,11 +746,12 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::data(qint64 forMSecsSinceEpoch) cons
const QWinTransitionRule &rule = m_tranRules.at(ruleIndex); const QWinTransitionRule &rule = m_tranRules.at(ruleIndex);
// Does this rule's period include any transition at all ? // Does this rule's period include any transition at all ?
if (rule.standardTimeRule.wMonth > 0 || rule.daylightTimeRule.wMonth > 0) { if (rule.standardTimeRule.wMonth > 0 || rule.daylightTimeRule.wMonth > 0) {
const int endYear = qMax(rule.startYear, year - 1); int prior = year == 1 ? -1 : year - 1; // No year 0.
const int endYear = qMax(rule.startYear, prior);
while (year >= endYear) { while (year >= endYear) {
const int newYearOffset = (year <= rule.startYear && ruleIndex > 0) const int newYearOffset = (year <= rule.startYear && ruleIndex > 0)
? yearEndOffset(m_tranRules.at(ruleIndex - 1), year - 1) ? yearEndOffset(m_tranRules.at(ruleIndex - 1), prior)
: yearEndOffset(rule, year - 1); : yearEndOffset(rule, prior);
const TransitionTimePair pair(rule, year, newYearOffset); const TransitionTimePair pair(rule, year, newYearOffset);
bool isDst = false; bool isDst = false;
if (pair.std != invalidMSecs() && pair.std <= forMSecsSinceEpoch) { if (pair.std != invalidMSecs() && pair.std <= forMSecsSinceEpoch) {
@ -755,7 +759,8 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::data(qint64 forMSecsSinceEpoch) cons
} else if (pair.dst != invalidMSecs() && pair.dst <= forMSecsSinceEpoch) { } else if (pair.dst != invalidMSecs() && pair.dst <= forMSecsSinceEpoch) {
isDst = true; isDst = true;
} else { } else {
--year; // Try an earlier year for this rule (once). year = prior; // Try an earlier year for this rule (once).
prior = year == 1 ? -1 : year - 1; // No year 0.
continue; continue;
} }
return ruleToData(rule, forMSecsSinceEpoch, return ruleToData(rule, forMSecsSinceEpoch,
@ -767,8 +772,11 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::data(qint64 forMSecsSinceEpoch) cons
// No transition, no DST, use the year's standard time. // No transition, no DST, use the year's standard time.
return ruleToData(rule, forMSecsSinceEpoch, QTimeZone::StandardTime); return ruleToData(rule, forMSecsSinceEpoch, QTimeZone::StandardTime);
} }
if (year >= rule.startYear) if (year >= rule.startYear) {
year = rule.startYear - 1; // Seek last transition in new rule. year = rule.startYear - 1; // Seek last transition in new rule.
if (!year)
--year;
}
} }
// We don't have relevant data :-( // We don't have relevant data :-(
return invalidData(); return invalidData();
@ -795,9 +803,10 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::nextTransition(qint64 afterMSecsSinc
year = rule.startYear; // Seek first transition in this rule. year = rule.startYear; // Seek first transition in this rule.
const int endYear = ruleIndex + 1 < m_tranRules.count() const int endYear = ruleIndex + 1 < m_tranRules.count()
? qMin(m_tranRules.at(ruleIndex + 1).startYear, year + 2) : (year + 2); ? qMin(m_tranRules.at(ruleIndex + 1).startYear, year + 2) : (year + 2);
int prior = year == 1 ? -1 : year - 1; // No year 0.
int newYearOffset = (year <= rule.startYear && ruleIndex > 0) int newYearOffset = (year <= rule.startYear && ruleIndex > 0)
? yearEndOffset(m_tranRules.at(ruleIndex - 1), year - 1) ? yearEndOffset(m_tranRules.at(ruleIndex - 1), prior)
: yearEndOffset(rule, year - 1); : yearEndOffset(rule, prior);
while (year < endYear) { while (year < endYear) {
const TransitionTimePair pair(rule, year, newYearOffset); const TransitionTimePair pair(rule, year, newYearOffset);
bool isDst = false; bool isDst = false;
@ -810,7 +819,9 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::nextTransition(qint64 afterMSecsSinc
newYearOffset = rule.standardTimeBias; newYearOffset = rule.standardTimeBias;
if (pair.dst > pair.std) if (pair.dst > pair.std)
newYearOffset += rule.daylightTimeBias; newYearOffset += rule.daylightTimeBias;
++year; // Try a later year for this rule (once). // Try a later year for this rule (once).
prior = year;
year = year == -1 ? 1 : year + 1; // No year 0
continue; continue;
} }
@ -837,11 +848,12 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::previousTransition(qint64 beforeMSec
const QWinTransitionRule &rule = m_tranRules.at(ruleIndex); const QWinTransitionRule &rule = m_tranRules.at(ruleIndex);
// Does this rule's period include any transition at all ? // Does this rule's period include any transition at all ?
if (rule.standardTimeRule.wMonth > 0 || rule.daylightTimeRule.wMonth > 0) { if (rule.standardTimeRule.wMonth > 0 || rule.daylightTimeRule.wMonth > 0) {
const int endYear = qMax(rule.startYear, year - 1); int prior = year == 1 ? -1 : year - 1; // No year 0.
const int endYear = qMax(rule.startYear, prior);
while (year >= endYear) { while (year >= endYear) {
const int newYearOffset = (year <= rule.startYear && ruleIndex > 0) const int newYearOffset = (year <= rule.startYear && ruleIndex > 0)
? yearEndOffset(m_tranRules.at(ruleIndex - 1), year - 1) ? yearEndOffset(m_tranRules.at(ruleIndex - 1), prior)
: yearEndOffset(rule, year - 1); : yearEndOffset(rule, prior);
const TransitionTimePair pair(rule, year, newYearOffset); const TransitionTimePair pair(rule, year, newYearOffset);
bool isDst = false; bool isDst = false;
if (pair.std != invalidMSecs() && pair.std < beforeMSecsSinceEpoch) { if (pair.std != invalidMSecs() && pair.std < beforeMSecsSinceEpoch) {
@ -849,7 +861,8 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::previousTransition(qint64 beforeMSec
} else if (pair.dst != invalidMSecs() && pair.dst < beforeMSecsSinceEpoch) { } else if (pair.dst != invalidMSecs() && pair.dst < beforeMSecsSinceEpoch) {
isDst = true; isDst = true;
} else { } else {
--year; // Try an earlier year for this rule (once). year = prior; // Try an earlier year for this rule (once).
prior = year == 1 ? -1 : year - 1; // No year 0.
continue; continue;
} }
if (isDst) if (isDst)
@ -863,8 +876,11 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::previousTransition(qint64 beforeMSec
// rule: // rule:
return ruleToData(rule, startOfTime, QTimeZone::StandardTime, false); return ruleToData(rule, startOfTime, QTimeZone::StandardTime, false);
} // else: no transition during rule's period } // else: no transition during rule's period
if (year >= rule.startYear) if (year >= rule.startYear) {
year = rule.startYear - 1; // Seek last transition in new rule year = rule.startYear - 1; // Seek last transition in new rule
if (!year)
--year;
}
} }
// Apparently no transition before the given time: // Apparently no transition before the given time:
return invalidData(); return invalidData();

View File

@ -150,7 +150,7 @@
// factory loader // factory loader
#include <qcoreapplication.h> #include <qcoreapplication.h>
#include <private/qfactoryloader_p.h> #include <private/qfactoryloader_p.h>
#include <QMutexLocker> #include <QtCore/private/qlocking_p.h>
// for qt_getImageText // for qt_getImageText
#include <private/qimage_p.h> #include <private/qimage_p.h>
@ -186,8 +186,8 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
QByteArray suffix; QByteArray suffix;
#ifndef QT_NO_IMAGEFORMATPLUGIN #ifndef QT_NO_IMAGEFORMATPLUGIN
static QMutex mutex; static QBasicMutex mutex;
QMutexLocker locker(&mutex); const auto locker = qt_scoped_lock(mutex);
typedef QMultiMap<int, QString> PluginKeyMap; typedef QMultiMap<int, QString> PluginKeyMap;

View File

@ -57,6 +57,7 @@
#include "qregexp.h" #include "qregexp.h"
#include "qregion.h" #include "qregion.h"
#include "qdebug.h" #include "qdebug.h"
#include <QtCore/private/qlocking_p.h>
#include <algorithm> #include <algorithm>
@ -1427,7 +1428,7 @@ void qt_init_picture_plugins()
typedef PluginKeyMap::const_iterator PluginKeyMapConstIterator; typedef PluginKeyMap::const_iterator PluginKeyMapConstIterator;
static QBasicMutex mutex; static QBasicMutex mutex;
QMutexLocker locker(&mutex); const auto locker = qt_scoped_lock(mutex);
static QFactoryLoader loader(QPictureFormatInterface_iid, static QFactoryLoader loader(QPictureFormatInterface_iid,
QStringLiteral("/pictureformats")); QStringLiteral("/pictureformats"));

View File

@ -58,6 +58,7 @@
#include <QtCore/private/qabstracteventdispatcher_p.h> #include <QtCore/private/qabstracteventdispatcher_p.h>
#include <QtCore/qmutex.h> #include <QtCore/qmutex.h>
#include <QtCore/private/qthread_p.h> #include <QtCore/private/qthread_p.h>
#include <QtCore/private/qlocking_p.h>
#include <QtCore/qdir.h> #include <QtCore/qdir.h>
#include <QtCore/qlibraryinfo.h> #include <QtCore/qlibraryinfo.h>
#include <QtCore/qnumeric.h> #include <QtCore/qnumeric.h>
@ -3305,7 +3306,7 @@ void QGuiApplicationPrivate::applyWindowGeometrySpecificationTo(QWindow *window)
QFont QGuiApplication::font() QFont QGuiApplication::font()
{ {
Q_ASSERT_X(QGuiApplicationPrivate::self, "QGuiApplication::font()", "no QGuiApplication instance"); Q_ASSERT_X(QGuiApplicationPrivate::self, "QGuiApplication::font()", "no QGuiApplication instance");
QMutexLocker locker(&applicationFontMutex); const auto locker = qt_scoped_lock(applicationFontMutex);
initFontUnlocked(); initFontUnlocked();
return *QGuiApplicationPrivate::app_font; return *QGuiApplicationPrivate::app_font;
} }
@ -3317,7 +3318,7 @@ QFont QGuiApplication::font()
*/ */
void QGuiApplication::setFont(const QFont &font) void QGuiApplication::setFont(const QFont &font)
{ {
QMutexLocker locker(&applicationFontMutex); auto locker = qt_unique_lock(applicationFontMutex);
const bool emitChange = !QGuiApplicationPrivate::app_font const bool emitChange = !QGuiApplicationPrivate::app_font
|| (*QGuiApplicationPrivate::app_font != font); || (*QGuiApplicationPrivate::app_font != font);
if (!QGuiApplicationPrivate::app_font) if (!QGuiApplicationPrivate::app_font)
@ -4081,7 +4082,7 @@ void QGuiApplicationPrivate::notifyThemeChanged()
sendApplicationPaletteChange(); sendApplicationPaletteChange();
} }
if (!(applicationResourceFlags & ApplicationFontExplicitlySet)) { if (!(applicationResourceFlags & ApplicationFontExplicitlySet)) {
QMutexLocker locker(&applicationFontMutex); const auto locker = qt_scoped_lock(applicationFontMutex);
clearFontUnlocked(); clearFontUnlocked();
initFontUnlocked(); initFontUnlocked();
} }

View File

@ -680,8 +680,11 @@ QDpi QHighDpiScaling::logicalDpi(const QScreen *screen)
if (!screen || !screen->handle()) if (!screen || !screen->handle())
return QDpi(96, 96); return QDpi(96, 96);
if (!m_usePixelDensity) if (!m_usePixelDensity) {
return QPlatformScreen::overrideDpi(screen->handle()->logicalDpi()); const qreal screenScaleFactor = screenSubfactor(screen->handle());
const QDpi dpi = QPlatformScreen::overrideDpi(screen->handle()->logicalDpi());
return QDpi{ dpi.first / screenScaleFactor, dpi.second / screenScaleFactor };
}
const qreal scaleFactor = rawScaleFactor(screen->handle()); const qreal scaleFactor = rawScaleFactor(screen->handle());
const qreal roundedScaleFactor = roundScaleFactor(scaleFactor); const qreal roundedScaleFactor = roundScaleFactor(scaleFactor);

View File

@ -45,6 +45,7 @@
#include <QtCore/QThreadStorage> #include <QtCore/QThreadStorage>
#include <QtCore/QThread> #include <QtCore/QThread>
#include <QtCore/private/qlocking_p.h>
#include <QtGui/private/qguiapplication_p.h> #include <QtGui/private/qguiapplication_p.h>
#include <QtGui/private/qopengl_p.h> #include <QtGui/private/qopengl_p.h>
@ -1442,7 +1443,7 @@ QOpenGLContextGroup *QOpenGLContextGroup::currentContextGroup()
void QOpenGLContextGroupPrivate::addContext(QOpenGLContext *ctx) void QOpenGLContextGroupPrivate::addContext(QOpenGLContext *ctx)
{ {
QMutexLocker locker(&m_mutex); const auto locker = qt_scoped_lock(m_mutex);
m_refs.ref(); m_refs.ref();
m_shares << ctx; m_shares << ctx;
} }
@ -1454,7 +1455,7 @@ void QOpenGLContextGroupPrivate::removeContext(QOpenGLContext *ctx)
bool deleteObject = false; bool deleteObject = false;
{ {
QMutexLocker locker(&m_mutex); const auto locker = qt_scoped_lock(m_mutex);
m_shares.removeOne(ctx); m_shares.removeOne(ctx);
if (ctx == m_context && !m_shares.isEmpty()) if (ctx == m_context && !m_shares.isEmpty())
@ -1502,7 +1503,7 @@ void QOpenGLContextGroupPrivate::cleanup()
void QOpenGLContextGroupPrivate::deletePendingResources(QOpenGLContext *ctx) void QOpenGLContextGroupPrivate::deletePendingResources(QOpenGLContext *ctx)
{ {
QMutexLocker locker(&m_mutex); const auto locker = qt_scoped_lock(m_mutex);
const QList<QOpenGLSharedResource *> pending = m_pendingDeletion; const QList<QOpenGLSharedResource *> pending = m_pendingDeletion;
m_pendingDeletion.clear(); m_pendingDeletion.clear();
@ -1543,7 +1544,7 @@ void QOpenGLContextGroupPrivate::deletePendingResources(QOpenGLContext *ctx)
QOpenGLSharedResource::QOpenGLSharedResource(QOpenGLContextGroup *group) QOpenGLSharedResource::QOpenGLSharedResource(QOpenGLContextGroup *group)
: m_group(group) : m_group(group)
{ {
QMutexLocker locker(&m_group->d_func()->m_mutex); const auto locker = qt_scoped_lock(m_group->d_func()->m_mutex);
m_group->d_func()->m_sharedResources << this; m_group->d_func()->m_sharedResources << this;
} }
@ -1559,7 +1560,7 @@ void QOpenGLSharedResource::free()
return; return;
} }
QMutexLocker locker(&m_group->d_func()->m_mutex); const auto locker = qt_scoped_lock(m_group->d_func()->m_mutex);
m_group->d_func()->m_sharedResources.removeOne(this); m_group->d_func()->m_sharedResources.removeOne(this);
m_group->d_func()->m_pendingDeletion << this; m_group->d_func()->m_pendingDeletion << this;

View File

@ -228,7 +228,7 @@ TouchDevices::TouchDevices()
*/ */
QList<const QTouchDevice *> QTouchDevice::devices() QList<const QTouchDevice *> QTouchDevice::devices()
{ {
QMutexLocker lock(&devicesMutex); const auto locker = qt_scoped_lock(devicesMutex);
return deviceList->list; return deviceList->list;
} }
@ -237,13 +237,13 @@ QList<const QTouchDevice *> QTouchDevice::devices()
*/ */
bool QTouchDevicePrivate::isRegistered(const QTouchDevice *dev) bool QTouchDevicePrivate::isRegistered(const QTouchDevice *dev)
{ {
QMutexLocker locker(&devicesMutex); const auto locker = qt_scoped_lock(devicesMutex);
return deviceList->list.contains(dev); return deviceList->list.contains(dev);
} }
const QTouchDevice *QTouchDevicePrivate::deviceById(quint8 id) const QTouchDevice *QTouchDevicePrivate::deviceById(quint8 id)
{ {
QMutexLocker locker(&devicesMutex); const auto locker = qt_scoped_lock(devicesMutex);
for (const QTouchDevice *dev : qAsConst(deviceList->list)) for (const QTouchDevice *dev : qAsConst(deviceList->list))
if (QTouchDevicePrivate::get(const_cast<QTouchDevice *>(dev))->id == id) if (QTouchDevicePrivate::get(const_cast<QTouchDevice *>(dev))->id == id)
return dev; return dev;
@ -255,7 +255,7 @@ const QTouchDevice *QTouchDevicePrivate::deviceById(quint8 id)
*/ */
void QTouchDevicePrivate::registerDevice(const QTouchDevice *dev) void QTouchDevicePrivate::registerDevice(const QTouchDevice *dev)
{ {
QMutexLocker lock(&devicesMutex); const auto locker = qt_scoped_lock(devicesMutex);
deviceList->list.append(dev); deviceList->list.append(dev);
} }
@ -264,7 +264,7 @@ void QTouchDevicePrivate::registerDevice(const QTouchDevice *dev)
*/ */
void QTouchDevicePrivate::unregisterDevice(const QTouchDevice *dev) void QTouchDevicePrivate::unregisterDevice(const QTouchDevice *dev)
{ {
QMutexLocker lock(&devicesMutex); const auto locker = qt_scoped_lock(devicesMutex);
deviceList->list.removeOne(dev); deviceList->list.removeOne(dev);
} }

View File

@ -62,17 +62,16 @@ class QColorVector
{ {
public: public:
QColorVector() = default; QColorVector() = default;
Q_DECL_CONSTEXPR QColorVector(float x, float y, float z) : x(x), y(y), z(z), _unused(0.0f) { } Q_DECL_CONSTEXPR QColorVector(float x, float y, float z) : x(x), y(y), z(z) { }
explicit Q_DECL_CONSTEXPR QColorVector(const QPointF &chr) // from XY chromaticity explicit Q_DECL_CONSTEXPR QColorVector(const QPointF &chr) // from XY chromaticity
: x(chr.x() / chr.y()) : x(chr.x() / chr.y())
, y(1.0f) , y(1.0f)
, z((1.0 - chr.x() - chr.y()) / chr.y()) , z((1.0 - chr.x() - chr.y()) / chr.y())
, _unused(0.0f)
{ } { }
float x; // X, x or red float x = 0.0f; // X, x or red
float y; // Y, y or green float y = 0.0f; // Y, y or green
float z; // Z, Y or blue float z = 0.0f; // Z, Y or blue
float _unused; float _unused = 0.0f;
friend inline bool operator==(const QColorVector &v1, const QColorVector &v2); friend inline bool operator==(const QColorVector &v1, const QColorVector &v2);
friend inline bool operator!=(const QColorVector &v1, const QColorVector &v2); friend inline bool operator!=(const QColorVector &v1, const QColorVector &v2);
@ -81,7 +80,6 @@ public:
return !x && !y && !z; return !x && !y && !z;
} }
static Q_DECL_CONSTEXPR QColorVector null() { return QColorVector(0.0f, 0.0f, 0.0f); }
static bool isValidChromaticity(const QPointF &chr) static bool isValidChromaticity(const QPointF &chr)
{ {
if (chr.x() < qreal(0.0) || chr.x() > qreal(1.0)) if (chr.x() < qreal(0.0) || chr.x() > qreal(1.0))
@ -187,10 +185,6 @@ public:
{ r.z, g.z, b.z } }; { r.z, g.z, b.z } };
} }
static QColorMatrix null()
{
return { QColorVector::null(), QColorVector::null(), QColorVector::null() };
}
static QColorMatrix identity() static QColorMatrix identity()
{ {
return { { 1.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f, 1.0f } }; return { { 1.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f, 1.0f } };

View File

@ -146,17 +146,11 @@ QColorMatrix QColorSpacePrimaries::toXyzMatrix() const
} }
QColorSpacePrivate::QColorSpacePrivate() QColorSpacePrivate::QColorSpacePrivate()
: primaries(QColorSpace::Primaries::Custom)
, transferFunction(QColorSpace::TransferFunction::Custom)
, gamma(0.0f)
, whitePoint(QColorVector::null())
, toXyz(QColorMatrix::null())
{ {
} }
QColorSpacePrivate::QColorSpacePrivate(QColorSpace::NamedColorSpace namedColorSpace) QColorSpacePrivate::QColorSpacePrivate(QColorSpace::NamedColorSpace namedColorSpace)
: namedColorSpace(namedColorSpace) : namedColorSpace(namedColorSpace)
, gamma(0.0f)
{ {
switch (namedColorSpace) { switch (namedColorSpace) {
case QColorSpace::SRgb: case QColorSpace::SRgb:
@ -282,7 +276,7 @@ void QColorSpacePrivate::initialize()
void QColorSpacePrivate::setToXyzMatrix() void QColorSpacePrivate::setToXyzMatrix()
{ {
if (primaries == QColorSpace::Primaries::Custom) { if (primaries == QColorSpace::Primaries::Custom) {
toXyz = QColorMatrix::null(); toXyz = QColorMatrix();
whitePoint = QColorVector::D50(); whitePoint = QColorVector::D50();
return; return;
} }

View File

@ -124,9 +124,9 @@ public:
static constexpr QColorSpace::NamedColorSpace Unknown = QColorSpace::NamedColorSpace(0); static constexpr QColorSpace::NamedColorSpace Unknown = QColorSpace::NamedColorSpace(0);
QColorSpace::NamedColorSpace namedColorSpace = Unknown; QColorSpace::NamedColorSpace namedColorSpace = Unknown;
QColorSpace::Primaries primaries; QColorSpace::Primaries primaries = QColorSpace::Primaries::Custom;
QColorSpace::TransferFunction transferFunction; QColorSpace::TransferFunction transferFunction = QColorSpace::TransferFunction::Custom;
float gamma; float gamma = 0.0f;
QColorVector whitePoint; QColorVector whitePoint;
QColorTrc trc[3]; QColorTrc trc[3];

View File

@ -612,6 +612,15 @@ static void storeOpaque(QRgba64 *dst, const QRgba64 *src, const QColorVector *bu
static constexpr qsizetype WorkBlockSize = 256; static constexpr qsizetype WorkBlockSize = 256;
template <typename T, int Count = 1>
class QUninitialized
{
public:
operator T*() { return reinterpret_cast<T *>(this); }
private:
alignas(T) char data[sizeof(T) * Count];
};
template<typename T> template<typename T>
void QColorTransformPrivate::apply(T *dst, const T *src, qsizetype count, TransformFlags flags) const void QColorTransformPrivate::apply(T *dst, const T *src, qsizetype count, TransformFlags flags) const
{ {
@ -623,7 +632,8 @@ void QColorTransformPrivate::apply(T *dst, const T *src, qsizetype count, Transf
bool doApplyMatrix = (colorMatrix != QColorMatrix::identity()); bool doApplyMatrix = (colorMatrix != QColorMatrix::identity());
QColorVector buffer[WorkBlockSize]; QUninitialized<QColorVector, WorkBlockSize> buffer;
qsizetype i = 0; qsizetype i = 0;
while (i < count) { while (i < count) {
const qsizetype len = qMin(count - i, WorkBlockSize); const qsizetype len = qMin(count - i, WorkBlockSize);

209
src/gui/rhi/cs_tdr.h Normal file
View File

@ -0,0 +1,209 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Gui module
**
** $QT_BEGIN_LICENSE:LGPL3$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <qglobal.h>
#ifdef Q_OS_WIN
#include <qt_windows.h>
#if 0
//
// Generated by Microsoft (R) HLSL Shader Compiler 10.1
//
//
// Buffer Definitions:
//
// cbuffer ConstantBuffer
// {
//
// uint zero; // Offset: 0 Size: 4
//
// }
//
//
// Resource Bindings:
//
// Name Type Format Dim HLSL Bind Count
// ------------------------------ ---------- ------- ----------- -------------- ------
// uav UAV uint buf u0 1
// ConstantBuffer cbuffer NA NA cb0 1
//
//
//
// Input signature:
//
// Name Index Mask Register SysValue Format Used
// -------------------- ----- ------ -------- -------- ------- ------
// no Input
//
// Output signature:
//
// Name Index Mask Register SysValue Format Used
// -------------------- ----- ------ -------- -------- ------- ------
// no Output
cs_5_0
dcl_globalFlags refactoringAllowed
dcl_constantbuffer CB0[1], immediateIndexed
dcl_uav_typed_buffer (uint,uint,uint,uint) u0
dcl_input vThreadID.x
dcl_thread_group 256, 1, 1
loop
breakc_nz cb0[0].x
store_uav_typed u0.xyzw, vThreadID.xxxx, cb0[0].xxxx
endloop
ret
// Approximately 5 instruction slots used
#endif
const BYTE g_killDeviceByTimingOut[] =
{
68, 88, 66, 67, 217, 62,
220, 38, 136, 51, 86, 245,
161, 96, 18, 35, 141, 17,
26, 13, 1, 0, 0, 0,
164, 2, 0, 0, 5, 0,
0, 0, 52, 0, 0, 0,
100, 1, 0, 0, 116, 1,
0, 0, 132, 1, 0, 0,
8, 2, 0, 0, 82, 68,
69, 70, 40, 1, 0, 0,
1, 0, 0, 0, 144, 0,
0, 0, 2, 0, 0, 0,
60, 0, 0, 0, 0, 5,
83, 67, 0, 1, 0, 0,
0, 1, 0, 0, 82, 68,
49, 49, 60, 0, 0, 0,
24, 0, 0, 0, 32, 0,
0, 0, 40, 0, 0, 0,
36, 0, 0, 0, 12, 0,
0, 0, 0, 0, 0, 0,
124, 0, 0, 0, 4, 0,
0, 0, 4, 0, 0, 0,
1, 0, 0, 0, 255, 255,
255, 255, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0,
0, 0, 128, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0,
0, 0, 0, 0, 117, 97,
118, 0, 67, 111, 110, 115,
116, 97, 110, 116, 66, 117,
102, 102, 101, 114, 0, 171,
128, 0, 0, 0, 1, 0,
0, 0, 168, 0, 0, 0,
16, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
208, 0, 0, 0, 0, 0,
0, 0, 4, 0, 0, 0,
2, 0, 0, 0, 220, 0,
0, 0, 0, 0, 0, 0,
255, 255, 255, 255, 0, 0,
0, 0, 255, 255, 255, 255,
0, 0, 0, 0, 122, 101,
114, 111, 0, 100, 119, 111,
114, 100, 0, 171, 0, 0,
19, 0, 1, 0, 1, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
213, 0, 0, 0, 77, 105,
99, 114, 111, 115, 111, 102,
116, 32, 40, 82, 41, 32,
72, 76, 83, 76, 32, 83,
104, 97, 100, 101, 114, 32,
67, 111, 109, 112, 105, 108,
101, 114, 32, 49, 48, 46,
49, 0, 73, 83, 71, 78,
8, 0, 0, 0, 0, 0,
0, 0, 8, 0, 0, 0,
79, 83, 71, 78, 8, 0,
0, 0, 0, 0, 0, 0,
8, 0, 0, 0, 83, 72,
69, 88, 124, 0, 0, 0,
80, 0, 5, 0, 31, 0,
0, 0, 106, 8, 0, 1,
89, 0, 0, 4, 70, 142,
32, 0, 0, 0, 0, 0,
1, 0, 0, 0, 156, 8,
0, 4, 0, 224, 17, 0,
0, 0, 0, 0, 68, 68,
0, 0, 95, 0, 0, 2,
18, 0, 2, 0, 155, 0,
0, 4, 0, 1, 0, 0,
1, 0, 0, 0, 1, 0,
0, 0, 48, 0, 0, 1,
3, 0, 4, 4, 10, 128,
32, 0, 0, 0, 0, 0,
0, 0, 0, 0, 164, 0,
0, 7, 242, 224, 17, 0,
0, 0, 0, 0, 6, 0,
2, 0, 6, 128, 32, 0,
0, 0, 0, 0, 0, 0,
0, 0, 22, 0, 0, 1,
62, 0, 0, 1, 83, 84,
65, 84, 148, 0, 0, 0,
5, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 2, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
1, 0, 0, 0
};
#endif // Q_OS_WIN

View File

@ -439,6 +439,18 @@ Q_LOGGING_CATEGORY(QRHI_LOG_INFO, "qt.rhi.general")
visible in external GPU debugging tools will not be available and functions visible in external GPU debugging tools will not be available and functions
like QRhiCommandBuffer::debugMarkBegin() will become a no-op. Avoid like QRhiCommandBuffer::debugMarkBegin() will become a no-op. Avoid
enabling in production builds as it may involve a performance penalty. enabling in production builds as it may involve a performance penalty.
\value PreferSoftwareRenderer Indicates that backends should prefer
choosing an adapter or physical device that renders in software on the CPU.
For example, with Direct3D there is typically a "Basic Render Driver"
adapter available with \c{DXGI_ADAPTER_FLAG_SOFTWARE}. Setting this flag
requests the backend to choose that adapter over any other, as long as no
specific adapter was forced by other backend-specific means. With Vulkan
this maps to preferring physical devices with
\c{VK_PHYSICAL_DEVICE_TYPE_CPU}. When not available, or when it is not
possible to decide if an adapter/device is software-based, this flag is
ignored. It may also be ignored with graphics APIs that have no concept and
means of enumerating adapters/devices.
*/ */
/*! /*!
@ -455,8 +467,8 @@ Q_LOGGING_CATEGORY(QRHI_LOG_INFO, "qt.rhi.general")
\value FrameOpDeviceLost The graphics device was lost. This can be \value FrameOpDeviceLost The graphics device was lost. This can be
recoverable by attempting to repeat the operation (such as, beginFrame()) recoverable by attempting to repeat the operation (such as, beginFrame())
and releasing and reinitializing all objects backed by native graphics after releasing and reinitializing all objects backed by native graphics
resources. resources. See isDeviceLost().
*/ */
/*! /*!
@ -673,7 +685,7 @@ bool operator!=(const QRhiDepthStencilClearValue &a, const QRhiDepthStencilClear
*/ */
uint qHash(const QRhiDepthStencilClearValue &v, uint seed) Q_DECL_NOTHROW uint qHash(const QRhiDepthStencilClearValue &v, uint seed) Q_DECL_NOTHROW
{ {
return seed * (qFloor(v.depthClearValue() * 100) + v.stencilClearValue()); return seed * (uint(qFloor(qreal(v.depthClearValue()) * 100)) + v.stencilClearValue());
} }
#ifndef QT_NO_DEBUG_STREAM #ifndef QT_NO_DEBUG_STREAM
@ -768,7 +780,8 @@ bool operator!=(const QRhiViewport &a, const QRhiViewport &b) Q_DECL_NOTHROW
uint qHash(const QRhiViewport &v, uint seed) Q_DECL_NOTHROW uint qHash(const QRhiViewport &v, uint seed) Q_DECL_NOTHROW
{ {
const std::array<float, 4> r = v.viewport(); const std::array<float, 4> r = v.viewport();
return seed + r[0] + r[1] + r[2] + r[3] + qFloor(v.minDepth() * 100) + qFloor(v.maxDepth() * 100); return seed + uint(r[0]) + uint(r[1]) + uint(r[2]) + uint(r[3])
+ uint(qFloor(qreal(v.minDepth()) * 100)) + uint(qFloor(qreal(v.maxDepth()) * 100));
} }
#ifndef QT_NO_DEBUG_STREAM #ifndef QT_NO_DEBUG_STREAM
@ -850,7 +863,7 @@ bool operator!=(const QRhiScissor &a, const QRhiScissor &b) Q_DECL_NOTHROW
uint qHash(const QRhiScissor &v, uint seed) Q_DECL_NOTHROW uint qHash(const QRhiScissor &v, uint seed) Q_DECL_NOTHROW
{ {
const std::array<int, 4> r = v.scissor(); const std::array<int, 4> r = v.scissor();
return seed + r[0] + r[1] + r[2] + r[3]; return seed + uint(r[0]) + uint(r[1]) + uint(r[2]) + uint(r[3]);
} }
#ifndef QT_NO_DEBUG_STREAM #ifndef QT_NO_DEBUG_STREAM
@ -1136,7 +1149,7 @@ bool operator!=(const QRhiVertexInputAttribute &a, const QRhiVertexInputAttribut
*/ */
uint qHash(const QRhiVertexInputAttribute &v, uint seed) Q_DECL_NOTHROW uint qHash(const QRhiVertexInputAttribute &v, uint seed) Q_DECL_NOTHROW
{ {
return seed + v.binding() + v.location() + v.format() + v.offset(); return seed + uint(v.binding()) + uint(v.location()) + uint(v.format()) + v.offset();
} }
#ifndef QT_NO_DEBUG_STREAM #ifndef QT_NO_DEBUG_STREAM
@ -3001,7 +3014,7 @@ bool operator!=(const QRhiShaderResourceBinding &a, const QRhiShaderResourceBind
uint qHash(const QRhiShaderResourceBinding &b, uint seed) Q_DECL_NOTHROW uint qHash(const QRhiShaderResourceBinding &b, uint seed) Q_DECL_NOTHROW
{ {
const char *u = reinterpret_cast<const char *>(&b.d->u); const char *u = reinterpret_cast<const char *>(&b.d->u);
return seed + b.d->binding + 10 * b.d->stage + 100 * b.d->type return seed + uint(b.d->binding) + 10 * uint(b.d->stage) + 100 * uint(b.d->type)
+ qHash(QByteArray::fromRawData(u, sizeof(b.d->u)), seed); + qHash(QByteArray::fromRawData(u, sizeof(b.d->u)), seed);
} }
@ -3457,10 +3470,18 @@ QRhiResource::Type QRhiGraphicsPipeline::resourceType() const
Flag values to describe swapchain properties Flag values to describe swapchain properties
\value SurfaceHasPreMulAlpha Indicates that the target surface has \value SurfaceHasPreMulAlpha Indicates that the target surface has
transparency with premultiplied alpha. transparency with premultiplied alpha. For example, this is what Qt Quick
uses when the alpha channel is enabled on the target QWindow, because the
scenegraph rendrerer always outputs fragments with alpha multiplied into
the red, green, and blue values. To ensure identical behavior across
platforms, always set QSurfaceFormat::alphaBufferSize() to a non-zero value
on the target QWindow whenever this flag is set on the swapchain.
\value SurfaceHasNonPreMulAlpha Indicates the target surface has \value SurfaceHasNonPreMulAlpha Indicates the target surface has
transparencyt with non-premultiplied alpha. transparency with non-premultiplied alpha. Be aware that this may not be
supported on some systems, if the system compositor always expects content
with premultiplied alpha. In that case the behavior with this flag set is
expected to be equivalent to SurfaceHasPreMulAlpha.
\value sRGB Requests to pick an sRGB format for the swapchain and/or its \value sRGB Requests to pick an sRGB format for the swapchain and/or its
render target views, where applicable. Note that this implies that sRGB render target views, where applicable. Note that this implies that sRGB
@ -3823,8 +3844,8 @@ void QRhiImplementation::compressedFormatInfo(QRhiTexture::Format format, const
break; break;
} }
const quint32 wblocks = (size.width() + xdim - 1) / xdim; const quint32 wblocks = uint((size.width() + xdim - 1) / xdim);
const quint32 hblocks = (size.height() + ydim - 1) / ydim; const quint32 hblocks = uint((size.height() + ydim - 1) / ydim);
if (bpl) if (bpl)
*bpl = wblocks * blockSize; *bpl = wblocks * blockSize;
@ -3880,9 +3901,9 @@ void QRhiImplementation::textureFormatInfo(QRhiTexture::Format format, const QSi
} }
if (bpl) if (bpl)
*bpl = size.width() * bpc; *bpl = uint(size.width()) * bpc;
if (byteSize) if (byteSize)
*byteSize = size.width() * size.height() * bpc; *byteSize = uint(size.width() * size.height()) * bpc;
} }
// Approximate because it excludes subresource alignment or multisampling. // Approximate because it excludes subresource alignment or multisampling.
@ -3892,12 +3913,12 @@ quint32 QRhiImplementation::approxByteSizeForTexture(QRhiTexture::Format format,
quint32 approxSize = 0; quint32 approxSize = 0;
for (int level = 0; level < mipCount; ++level) { for (int level = 0; level < mipCount; ++level) {
quint32 byteSize = 0; quint32 byteSize = 0;
const QSize size(qFloor(float(qMax(1, baseSize.width() >> level))), const QSize size(qFloor(qreal(qMax(1, baseSize.width() >> level))),
qFloor(float(qMax(1, baseSize.height() >> level)))); qFloor(qreal(qMax(1, baseSize.height() >> level))));
textureFormatInfo(format, size, nullptr, &byteSize); textureFormatInfo(format, size, nullptr, &byteSize);
approxSize += byteSize; approxSize += byteSize;
} }
approxSize *= layerCount; approxSize *= uint(layerCount);
return approxSize; return approxSize;
} }
@ -5001,10 +5022,17 @@ const QRhiNativeHandles *QRhi::nativeHandles()
has to ensure external OpenGL code provided by the application can still has to ensure external OpenGL code provided by the application can still
run like it did before with direct usage of OpenGL, as long as the QRhi is run like it did before with direct usage of OpenGL, as long as the QRhi is
using the OpenGL backend. using the OpenGL backend.
\return false when failed, similarly to QOpenGLContext::makeCurrent(). When
the operation failed, isDeviceLost() can be called to determine if there
was a loss of context situation. Such a check is equivalent to checking via
QOpenGLContext::isValid().
\sa QOpenGLContext::makeCurrent(), QOpenGLContext::isValid()
*/ */
void QRhi::makeThreadLocalNativeContextCurrent() bool QRhi::makeThreadLocalNativeContextCurrent()
{ {
d->makeThreadLocalNativeContextCurrent(); return d->makeThreadLocalNativeContextCurrent();
} }
/*! /*!
@ -5036,6 +5064,53 @@ void QRhi::releaseCachedResources()
d->releaseCachedResources(); d->releaseCachedResources();
} }
/*!
\return true if the graphics device was lost.
The loss of the device is typically detected in beginFrame(), endFrame() or
QRhiSwapChain::buildOrResize(), depending on the backend and the underlying
native APIs. The most common is endFrame() because that is where presenting
happens. With some backends QRhiSwapChain::buildOrResize() can also fail
due to a device loss. Therefore this function is provided as a generic way
to check if a device loss was detected by a previous operation.
When the device is lost, no further operations should be done via the QRhi.
Rather, all QRhi resources should be released, followed by destroying the
QRhi. A new QRhi can then be attempted to be created. If successful, all
graphics resources must be reinitialized. If not, try again later,
repeatedly.
While simple applications may decide to not care about device loss,
on the commonly used desktop platforms a device loss can happen
due to a variety of reasons, including physically disconnecting the
graphics adapter, disabling the device or driver, uninstalling or upgrading
the graphics driver, or due to errors that lead to a graphics device reset.
Some of these can happen under perfectly normal circumstances as well, for
example the upgrade of the graphics driver to a newer version is a common
task that can happen at any time while a Qt application is running. Users
may very well expect applications to be able to survive this, even when the
application is actively using an API like OpenGL or Direct3D.
Qt's own frameworks built on top of QRhi, such as, Qt Quick, can be
expected to handle and take appropriate measures when a device loss occurs.
If the data for graphics resources, such as textures and buffers, are still
available on the CPU side, such an event may not be noticeable on the
application level at all since graphics resources can seamlessly be
reinitialized then. However, applications and libraries working directly
with QRhi are expected to be prepared to check and handle device loss
situations themselves.
\note With OpenGL, applications may need to opt-in to context reset
notifications by setting QSurfaceFormat::ResetNotification on the
QOpenGLContext. This is typically done by enabling the flag in
QRhiGles2InitParams::format. Keep in mind however that some systems may
generate context resets situations even when this flag is not set.
*/
bool QRhi::isDeviceLost() const
{
return d->isDeviceLost();
}
/*! /*!
\return a new graphics pipeline resource. \return a new graphics pipeline resource.
@ -5197,7 +5272,17 @@ QRhiSwapChain *QRhi::newSwapChain()
\endlist \endlist
\sa endFrame(), beginOffscreenFrame() \return QRhi::FrameOpSuccess on success, or another QRhi::FrameOpResult
value on failure. Some of these should be treated as soft, "try again
later" type of errors: When QRhi::FrameOpSwapChainOutOfDate is returned,
the swapchain is to be resized or updated by calling
QRhiSwapChain::buildOrResize(). The application should then attempt to
generate a new frame. QRhi::FrameOpDeviceLost means the graphics device is
lost but this may also be recoverable by releasing all resources, including
the QRhi itself, and then recreating all resources. See isDeviceLost() for
further discussion.
\sa endFrame(), beginOffscreenFrame(), isDeviceLost()
*/ */
QRhi::FrameOpResult QRhi::beginFrame(QRhiSwapChain *swapChain, BeginFrameFlags flags) QRhi::FrameOpResult QRhi::beginFrame(QRhiSwapChain *swapChain, BeginFrameFlags flags)
{ {
@ -5222,7 +5307,17 @@ QRhi::FrameOpResult QRhi::beginFrame(QRhiSwapChain *swapChain, BeginFrameFlags f
Passing QRhi::SkipPresent skips queuing the Present command or calling Passing QRhi::SkipPresent skips queuing the Present command or calling
swapBuffers. swapBuffers.
\sa beginFrame() \return QRhi::FrameOpSuccess on success, or another QRhi::FrameOpResult
value on failure. Some of these should be treated as soft, "try again
later" type of errors: When QRhi::FrameOpSwapChainOutOfDate is returned,
the swapchain is to be resized or updated by calling
QRhiSwapChain::buildOrResize(). The application should then attempt to
generate a new frame. QRhi::FrameOpDeviceLost means the graphics device is
lost but this may also be recoverable by releasing all resources, including
the QRhi itself, and then recreating all resources. See isDeviceLost() for
further discussion.
\sa beginFrame(), isDeviceLost()
*/ */
QRhi::FrameOpResult QRhi::endFrame(QRhiSwapChain *swapChain, EndFrameFlags flags) QRhi::FrameOpResult QRhi::endFrame(QRhiSwapChain *swapChain, EndFrameFlags flags)
{ {

View File

@ -1294,7 +1294,8 @@ public:
enum Flag { enum Flag {
EnableProfiling = 1 << 0, EnableProfiling = 1 << 0,
EnableDebugMarkers = 1 << 1 EnableDebugMarkers = 1 << 1,
PreferSoftwareRenderer = 1 << 2
}; };
Q_DECLARE_FLAGS(Flags, Flag) Q_DECLARE_FLAGS(Flags, Flag)
@ -1413,7 +1414,7 @@ public:
int resourceLimit(ResourceLimit limit) const; int resourceLimit(ResourceLimit limit) const;
const QRhiNativeHandles *nativeHandles(); const QRhiNativeHandles *nativeHandles();
void makeThreadLocalNativeContextCurrent(); bool makeThreadLocalNativeContextCurrent();
QRhiProfiler *profiler(); QRhiProfiler *profiler();
@ -1422,6 +1423,8 @@ public:
void releaseCachedResources(); void releaseCachedResources();
bool isDeviceLost() const;
protected: protected:
QRhi(); QRhi();

View File

@ -156,8 +156,9 @@ public:
virtual int resourceLimit(QRhi::ResourceLimit limit) const = 0; virtual int resourceLimit(QRhi::ResourceLimit limit) const = 0;
virtual const QRhiNativeHandles *nativeHandles() = 0; virtual const QRhiNativeHandles *nativeHandles() = 0;
virtual void sendVMemStatsToProfiler() = 0; virtual void sendVMemStatsToProfiler() = 0;
virtual void makeThreadLocalNativeContextCurrent() = 0; virtual bool makeThreadLocalNativeContextCurrent() = 0;
virtual void releaseCachedResources() = 0; virtual void releaseCachedResources() = 0;
virtual bool isDeviceLost() const = 0;
bool isCompressedFormat(QRhiTexture::Format format) const; bool isCompressedFormat(QRhiTexture::Format format) const;
void compressedFormatInfo(QRhiTexture::Format format, const QSize &size, void compressedFormatInfo(QRhiTexture::Format format, const QSize &size,

View File

@ -36,6 +36,7 @@
#include "qrhid3d11_p_p.h" #include "qrhid3d11_p_p.h"
#include "qshader_p.h" #include "qshader_p.h"
#include "cs_tdr.h"
#include <QWindow> #include <QWindow>
#include <QOperatingSystemVersion> #include <QOperatingSystemVersion>
#include <qmath.h> #include <qmath.h>
@ -118,10 +119,20 @@ QT_BEGIN_NAMESPACE
\c{ID3D11Texture2D *}. \c{ID3D11Texture2D *}.
*/ */
// help mingw with its ancient sdk headers
#ifndef DXGI_ADAPTER_FLAG_SOFTWARE
#define DXGI_ADAPTER_FLAG_SOFTWARE 2
#endif
QRhiD3D11::QRhiD3D11(QRhiD3D11InitParams *params, QRhiD3D11NativeHandles *importDevice) QRhiD3D11::QRhiD3D11(QRhiD3D11InitParams *params, QRhiD3D11NativeHandles *importDevice)
: ofr(this) : ofr(this),
deviceCurse(this)
{ {
debugLayer = params->enableDebugLayer; debugLayer = params->enableDebugLayer;
deviceCurse.framesToActivate = params->framesUntilKillingDeviceViaTdr;
deviceCurse.permanent = params->repeatDeviceKill;
importedDevice = importDevice != nullptr; importedDevice = importDevice != nullptr;
if (importedDevice) { if (importedDevice) {
dev = reinterpret_cast<ID3D11Device *>(importDevice->dev); dev = reinterpret_cast<ID3D11Device *>(importDevice->dev);
@ -155,7 +166,7 @@ static QString comErrorMessage(HRESULT hr)
} }
template <class Int> template <class Int>
static inline Int aligned(Int v, Int byteAlign) inline Int aligned(Int v, Int byteAlign)
{ {
return (v + byteAlign - 1) & ~(byteAlign - 1); return (v + byteAlign - 1) & ~(byteAlign - 1);
} }
@ -166,7 +177,7 @@ static IDXGIFactory1 *createDXGIFactory2()
if (QOperatingSystemVersion::current() > QOperatingSystemVersion::Windows7) { if (QOperatingSystemVersion::current() > QOperatingSystemVersion::Windows7) {
using PtrCreateDXGIFactory2 = HRESULT (WINAPI *)(UINT, REFIID, void **); using PtrCreateDXGIFactory2 = HRESULT (WINAPI *)(UINT, REFIID, void **);
QSystemLibrary dxgilib(QStringLiteral("dxgi")); QSystemLibrary dxgilib(QStringLiteral("dxgi"));
if (auto createDXGIFactory2 = (PtrCreateDXGIFactory2)dxgilib.resolve("CreateDXGIFactory2")) { if (auto createDXGIFactory2 = reinterpret_cast<PtrCreateDXGIFactory2>(dxgilib.resolve("CreateDXGIFactory2"))) {
const HRESULT hr = createDXGIFactory2(0, IID_IDXGIFactory2, reinterpret_cast<void **>(&result)); const HRESULT hr = createDXGIFactory2(0, IID_IDXGIFactory2, reinterpret_cast<void **>(&result));
if (FAILED(hr)) { if (FAILED(hr)) {
qWarning("CreateDXGIFactory2() failed to create DXGI factory: %s", qPrintable(comErrorMessage(hr))); qWarning("CreateDXGIFactory2() failed to create DXGI factory: %s", qPrintable(comErrorMessage(hr)));
@ -221,11 +232,29 @@ bool QRhiD3D11::create(QRhi::Flags flags)
int requestedAdapterIndex = -1; int requestedAdapterIndex = -1;
if (qEnvironmentVariableIsSet("QT_D3D_ADAPTER_INDEX")) if (qEnvironmentVariableIsSet("QT_D3D_ADAPTER_INDEX"))
requestedAdapterIndex = qEnvironmentVariableIntValue("QT_D3D_ADAPTER_INDEX"); requestedAdapterIndex = qEnvironmentVariableIntValue("QT_D3D_ADAPTER_INDEX");
for (int adapterIndex = 0; dxgiFactory->EnumAdapters1(adapterIndex, &adapter) != DXGI_ERROR_NOT_FOUND; ++adapterIndex) {
if (requestedAdapterIndex < 0 && flags.testFlag(QRhi::PreferSoftwareRenderer)) {
for (int adapterIndex = 0; dxgiFactory->EnumAdapters1(UINT(adapterIndex), &adapter) != DXGI_ERROR_NOT_FOUND; ++adapterIndex) {
DXGI_ADAPTER_DESC1 desc;
adapter->GetDesc1(&desc);
adapter->Release();
if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) {
requestedAdapterIndex = adapterIndex;
break;
}
}
}
for (int adapterIndex = 0; dxgiFactory->EnumAdapters1(UINT(adapterIndex), &adapter) != DXGI_ERROR_NOT_FOUND; ++adapterIndex) {
DXGI_ADAPTER_DESC1 desc; DXGI_ADAPTER_DESC1 desc;
adapter->GetDesc1(&desc); adapter->GetDesc1(&desc);
const QString name = QString::fromUtf16((char16_t *) desc.Description); const QString name = QString::fromUtf16(reinterpret_cast<char16_t *>(desc.Description));
qCDebug(QRHI_LOG_INFO, "Adapter %d: '%s' (flags 0x%x)", adapterIndex, qPrintable(name), desc.Flags); qCDebug(QRHI_LOG_INFO, "Adapter %d: '%s' (vendor 0x%X device 0x%X flags 0x%X)",
adapterIndex,
qPrintable(name),
desc.VendorId,
desc.DeviceId,
desc.Flags);
if (!adapterToUse && (requestedAdapterIndex < 0 || requestedAdapterIndex == adapterIndex)) { if (!adapterToUse && (requestedAdapterIndex < 0 || requestedAdapterIndex == adapterIndex)) {
adapterToUse = adapter; adapterToUse = adapter;
qCDebug(QRHI_LOG_INFO, " using this adapter"); qCDebug(QRHI_LOG_INFO, " using this adapter");
@ -261,9 +290,14 @@ bool QRhiD3D11::create(QRhi::Flags flags)
if (FAILED(context->QueryInterface(IID_ID3DUserDefinedAnnotation, reinterpret_cast<void **>(&annotations)))) if (FAILED(context->QueryInterface(IID_ID3DUserDefinedAnnotation, reinterpret_cast<void **>(&annotations))))
annotations = nullptr; annotations = nullptr;
deviceLost = false;
nativeHandlesStruct.dev = dev; nativeHandlesStruct.dev = dev;
nativeHandlesStruct.context = context; nativeHandlesStruct.context = context;
if (deviceCurse.framesToActivate > 0)
deviceCurse.initResources();
return true; return true;
} }
@ -281,6 +315,8 @@ void QRhiD3D11::destroy()
clearShaderCache(); clearShaderCache();
deviceCurse.releaseResources();
if (annotations) { if (annotations) {
annotations->Release(); annotations->Release();
annotations = nullptr; annotations = nullptr;
@ -332,9 +368,9 @@ DXGI_SAMPLE_DESC QRhiD3D11::effectiveSampleCount(int sampleCount) const
return desc; return desc;
} }
desc.Count = s; desc.Count = UINT(s);
if (s > 1) if (s > 1)
desc.Quality = D3D11_STANDARD_MULTISAMPLE_PATTERN; desc.Quality = UINT(D3D11_STANDARD_MULTISAMPLE_PATTERN);
else else
desc.Quality = 0; desc.Quality = 0;
@ -466,9 +502,10 @@ void QRhiD3D11::sendVMemStatsToProfiler()
// nothing to do here // nothing to do here
} }
void QRhiD3D11::makeThreadLocalNativeContextCurrent() bool QRhiD3D11::makeThreadLocalNativeContextCurrent()
{ {
// nothing to do here // not applicable
return false;
} }
void QRhiD3D11::releaseCachedResources() void QRhiD3D11::releaseCachedResources()
@ -476,6 +513,11 @@ void QRhiD3D11::releaseCachedResources()
clearShaderCache(); clearShaderCache();
} }
bool QRhiD3D11::isDeviceLost() const
{
return deviceLost;
}
QRhiRenderBuffer *QRhiD3D11::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize, QRhiRenderBuffer *QRhiD3D11::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
int sampleCount, QRhiRenderBuffer::Flags flags) int sampleCount, QRhiRenderBuffer::Flags flags)
{ {
@ -655,7 +697,7 @@ void QRhiD3D11::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind
uint *p = cmd.args.bindShaderResources.dynamicOffsetPairs; uint *p = cmd.args.bindShaderResources.dynamicOffsetPairs;
for (int i = 0; i < dynamicOffsetCount; ++i) { for (int i = 0; i < dynamicOffsetCount; ++i) {
const QRhiCommandBuffer::DynamicOffset &dynOfs(dynamicOffsets[i]); const QRhiCommandBuffer::DynamicOffset &dynOfs(dynamicOffsets[i]);
const uint binding = dynOfs.first; const uint binding = uint(dynOfs.first);
Q_ASSERT(aligned(dynOfs.second, quint32(256)) == dynOfs.second); Q_ASSERT(aligned(dynOfs.second, quint32(256)) == dynOfs.second);
const uint offsetInConstants = dynOfs.second / 16; const uint offsetInConstants = dynOfs.second / 16;
*p++ = binding; *p++ = binding;
@ -791,10 +833,10 @@ void QRhiD3D11::setBlendConstants(QRhiCommandBuffer *cb, const QColor &c)
QD3D11CommandBuffer::Command cmd; QD3D11CommandBuffer::Command cmd;
cmd.cmd = QD3D11CommandBuffer::Command::BlendConstants; cmd.cmd = QD3D11CommandBuffer::Command::BlendConstants;
cmd.args.blendConstants.ps = QRHI_RES(QD3D11GraphicsPipeline, cbD->currentGraphicsPipeline); cmd.args.blendConstants.ps = QRHI_RES(QD3D11GraphicsPipeline, cbD->currentGraphicsPipeline);
cmd.args.blendConstants.c[0] = c.redF(); cmd.args.blendConstants.c[0] = float(c.redF());
cmd.args.blendConstants.c[1] = c.greenF(); cmd.args.blendConstants.c[1] = float(c.greenF());
cmd.args.blendConstants.c[2] = c.blueF(); cmd.args.blendConstants.c[2] = float(c.blueF());
cmd.args.blendConstants.c[3] = c.alphaF(); cmd.args.blendConstants.c[3] = float(c.alphaF());
cbD->commands.append(cmd); cbD->commands.append(cmd);
} }
@ -992,8 +1034,14 @@ QRhi::FrameOpResult QRhiD3D11::endFrame(QRhiSwapChain *swapChain, QRhi::EndFrame
if (!flags.testFlag(QRhi::SkipPresent)) { if (!flags.testFlag(QRhi::SkipPresent)) {
const UINT presentFlags = 0; const UINT presentFlags = 0;
HRESULT hr = swapChainD->swapChain->Present(swapChainD->swapInterval, presentFlags); HRESULT hr = swapChainD->swapChain->Present(swapChainD->swapInterval, presentFlags);
if (FAILED(hr)) if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET) {
qWarning("Device loss detected in Present()");
deviceLost = true;
return QRhi::FrameOpDeviceLost;
} else if (FAILED(hr)) {
qWarning("Failed to present: %s", qPrintable(comErrorMessage(hr))); qWarning("Failed to present: %s", qPrintable(comErrorMessage(hr)));
return QRhi::FrameOpError;
}
// move on to the next buffer // move on to the next buffer
swapChainD->currentFrameSlot = (swapChainD->currentFrameSlot + 1) % QD3D11SwapChain::BUFFER_COUNT; swapChainD->currentFrameSlot = (swapChainD->currentFrameSlot + 1) % QD3D11SwapChain::BUFFER_COUNT;
@ -1003,6 +1051,20 @@ QRhi::FrameOpResult QRhiD3D11::endFrame(QRhiSwapChain *swapChain, QRhi::EndFrame
swapChainD->frameCount += 1; swapChainD->frameCount += 1;
contextState.currentSwapChain = nullptr; contextState.currentSwapChain = nullptr;
if (deviceCurse.framesToActivate > 0) {
deviceCurse.framesLeft -= 1;
if (deviceCurse.framesLeft == 0) {
deviceCurse.framesLeft = deviceCurse.framesToActivate;
if (!deviceCurse.permanent)
deviceCurse.framesToActivate = -1;
deviceCurse.activate();
} else if (deviceCurse.framesLeft % 100 == 0) {
qDebug("Impending doom: %d frames left", deviceCurse.framesLeft);
}
}
return QRhi::FrameOpSuccess; return QRhi::FrameOpSuccess;
} }
@ -1176,7 +1238,7 @@ QRhi::FrameOpResult QRhiD3D11::finish()
void QRhiD3D11::enqueueSubresUpload(QD3D11Texture *texD, QD3D11CommandBuffer *cbD, void QRhiD3D11::enqueueSubresUpload(QD3D11Texture *texD, QD3D11CommandBuffer *cbD,
int layer, int level, const QRhiTextureSubresourceUploadDescription &subresDesc) int layer, int level, const QRhiTextureSubresourceUploadDescription &subresDesc)
{ {
UINT subres = D3D11CalcSubresource(level, layer, texD->mipLevelCount); UINT subres = D3D11CalcSubresource(UINT(level), UINT(layer), texD->mipLevelCount);
const QPoint dp = subresDesc.destinationTopLeft(); const QPoint dp = subresDesc.destinationTopLeft();
D3D11_BOX box; D3D11_BOX box;
box.front = 0; box.front = 0;
@ -1207,13 +1269,13 @@ void QRhiD3D11::enqueueSubresUpload(QD3D11Texture *texD, QD3D11CommandBuffer *cb
} else { } else {
cmd.args.updateSubRes.src = cbD->retainImage(img); cmd.args.updateSubRes.src = cbD->retainImage(img);
} }
box.left = dp.x(); box.left = UINT(dp.x());
box.top = dp.y(); box.top = UINT(dp.y());
box.right = dp.x() + size.width(); box.right = UINT(dp.x() + size.width());
box.bottom = dp.y() + size.height(); box.bottom = UINT(dp.y() + size.height());
cmd.args.updateSubRes.hasDstBox = true; cmd.args.updateSubRes.hasDstBox = true;
cmd.args.updateSubRes.dstBox = box; cmd.args.updateSubRes.dstBox = box;
cmd.args.updateSubRes.srcRowPitch = bpl; cmd.args.updateSubRes.srcRowPitch = UINT(bpl);
} else if (!subresDesc.data().isEmpty() && isCompressedFormat(texD->m_format)) { } else if (!subresDesc.data().isEmpty() && isCompressedFormat(texD->m_format)) {
const QSize size = subresDesc.sourceSize().isEmpty() ? q->sizeForMipLevel(level, texD->m_pixelSize) const QSize size = subresDesc.sourceSize().isEmpty() ? q->sizeForMipLevel(level, texD->m_pixelSize)
: subresDesc.sourceSize(); : subresDesc.sourceSize();
@ -1223,10 +1285,10 @@ void QRhiD3D11::enqueueSubresUpload(QD3D11Texture *texD, QD3D11CommandBuffer *cb
// Everything must be a multiple of the block width and // Everything must be a multiple of the block width and
// height, so e.g. a mip level of size 2x2 will be 4x4 when it // height, so e.g. a mip level of size 2x2 will be 4x4 when it
// comes to the actual data. // comes to the actual data.
box.left = aligned(dp.x(), blockDim.width()); box.left = UINT(aligned(dp.x(), blockDim.width()));
box.top = aligned(dp.y(), blockDim.height()); box.top = UINT(aligned(dp.y(), blockDim.height()));
box.right = aligned(dp.x() + size.width(), blockDim.width()); box.right = UINT(aligned(dp.x() + size.width(), blockDim.width()));
box.bottom = aligned(dp.y() + size.height(), blockDim.height()); box.bottom = UINT(aligned(dp.y() + size.height(), blockDim.height()));
cmd.args.updateSubRes.hasDstBox = true; cmd.args.updateSubRes.hasDstBox = true;
cmd.args.updateSubRes.dstBox = box; cmd.args.updateSubRes.dstBox = box;
cmd.args.updateSubRes.src = cbD->retainData(subresDesc.data()); cmd.args.updateSubRes.src = cbD->retainData(subresDesc.data());
@ -1236,10 +1298,10 @@ void QRhiD3D11::enqueueSubresUpload(QD3D11Texture *texD, QD3D11CommandBuffer *cb
: subresDesc.sourceSize(); : subresDesc.sourceSize();
quint32 bpl = 0; quint32 bpl = 0;
textureFormatInfo(texD->m_format, size, &bpl, nullptr); textureFormatInfo(texD->m_format, size, &bpl, nullptr);
box.left = dp.x(); box.left = UINT(dp.x());
box.top = dp.y(); box.top = UINT(dp.y());
box.right = dp.x() + size.width(); box.right = UINT(dp.x() + size.width());
box.bottom = dp.y() + size.height(); box.bottom = UINT(dp.y() + size.height());
cmd.args.updateSubRes.hasDstBox = true; cmd.args.updateSubRes.hasDstBox = true;
cmd.args.updateSubRes.dstBox = box; cmd.args.updateSubRes.dstBox = box;
cmd.args.updateSubRes.src = cbD->retainData(subresDesc.data()); cmd.args.updateSubRes.src = cbD->retainData(subresDesc.data());
@ -1261,7 +1323,7 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
for (const QRhiResourceUpdateBatchPrivate::DynamicBufferUpdate &u : ud->dynamicBufferUpdates) { for (const QRhiResourceUpdateBatchPrivate::DynamicBufferUpdate &u : ud->dynamicBufferUpdates) {
QD3D11Buffer *bufD = QRHI_RES(QD3D11Buffer, u.buf); QD3D11Buffer *bufD = QRHI_RES(QD3D11Buffer, u.buf);
Q_ASSERT(bufD->m_type == QRhiBuffer::Dynamic); Q_ASSERT(bufD->m_type == QRhiBuffer::Dynamic);
memcpy(bufD->dynBuf.data() + u.offset, u.data.constData(), u.data.size()); memcpy(bufD->dynBuf.data() + u.offset, u.data.constData(), size_t(u.data.size()));
bufD->hasPendingDynamicUpdates = true; bufD->hasPendingDynamicUpdates = true;
} }
@ -1279,10 +1341,10 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
// since the ID3D11Buffer's size is rounded up to be a multiple of 256 // since the ID3D11Buffer's size is rounded up to be a multiple of 256
// while the data we have has the original size. // while the data we have has the original size.
D3D11_BOX box; D3D11_BOX box;
box.left = u.offset; box.left = UINT(u.offset);
box.top = box.front = 0; box.top = box.front = 0;
box.back = box.bottom = 1; box.back = box.bottom = 1;
box.right = u.offset + u.data.size(); // no -1: right, bottom, back are exclusive, see D3D11_BOX doc box.right = UINT(u.offset + u.data.size()); // no -1: right, bottom, back are exclusive, see D3D11_BOX doc
cmd.args.updateSubRes.hasDstBox = true; cmd.args.updateSubRes.hasDstBox = true;
cmd.args.updateSubRes.dstBox = box; cmd.args.updateSubRes.dstBox = box;
cbD->commands.append(cmd); cbD->commands.append(cmd);
@ -1301,25 +1363,25 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
Q_ASSERT(u.copy.src && u.copy.dst); Q_ASSERT(u.copy.src && u.copy.dst);
QD3D11Texture *srcD = QRHI_RES(QD3D11Texture, u.copy.src); QD3D11Texture *srcD = QRHI_RES(QD3D11Texture, u.copy.src);
QD3D11Texture *dstD = QRHI_RES(QD3D11Texture, u.copy.dst); QD3D11Texture *dstD = QRHI_RES(QD3D11Texture, u.copy.dst);
UINT srcSubRes = D3D11CalcSubresource(u.copy.desc.sourceLevel(), u.copy.desc.sourceLayer(), srcD->mipLevelCount); UINT srcSubRes = D3D11CalcSubresource(UINT(u.copy.desc.sourceLevel()), UINT(u.copy.desc.sourceLayer()), srcD->mipLevelCount);
UINT dstSubRes = D3D11CalcSubresource(u.copy.desc.destinationLevel(), u.copy.desc.destinationLayer(), dstD->mipLevelCount); UINT dstSubRes = D3D11CalcSubresource(UINT(u.copy.desc.destinationLevel()), UINT(u.copy.desc.destinationLayer()), dstD->mipLevelCount);
const QPoint dp = u.copy.desc.destinationTopLeft(); const QPoint dp = u.copy.desc.destinationTopLeft();
const QSize size = u.copy.desc.pixelSize().isEmpty() ? srcD->m_pixelSize : u.copy.desc.pixelSize(); const QSize size = u.copy.desc.pixelSize().isEmpty() ? srcD->m_pixelSize : u.copy.desc.pixelSize();
const QPoint sp = u.copy.desc.sourceTopLeft(); const QPoint sp = u.copy.desc.sourceTopLeft();
D3D11_BOX srcBox; D3D11_BOX srcBox;
srcBox.left = sp.x(); srcBox.left = UINT(sp.x());
srcBox.top = sp.y(); srcBox.top = UINT(sp.y());
srcBox.front = 0; srcBox.front = 0;
// back, right, bottom are exclusive // back, right, bottom are exclusive
srcBox.right = srcBox.left + size.width(); srcBox.right = srcBox.left + UINT(size.width());
srcBox.bottom = srcBox.top + size.height(); srcBox.bottom = srcBox.top + UINT(size.height());
srcBox.back = 1; srcBox.back = 1;
QD3D11CommandBuffer::Command cmd; QD3D11CommandBuffer::Command cmd;
cmd.cmd = QD3D11CommandBuffer::Command::CopySubRes; cmd.cmd = QD3D11CommandBuffer::Command::CopySubRes;
cmd.args.copySubRes.dst = dstD->tex; cmd.args.copySubRes.dst = dstD->tex;
cmd.args.copySubRes.dstSubRes = dstSubRes; cmd.args.copySubRes.dstSubRes = dstSubRes;
cmd.args.copySubRes.dstX = dp.x(); cmd.args.copySubRes.dstX = UINT(dp.x());
cmd.args.copySubRes.dstY = dp.y(); cmd.args.copySubRes.dstY = UINT(dp.y());
cmd.args.copySubRes.src = srcD->tex; cmd.args.copySubRes.src = srcD->tex;
cmd.args.copySubRes.srcSubRes = srcSubRes; cmd.args.copySubRes.srcSubRes = srcSubRes;
cmd.args.copySubRes.hasSrcBox = true; cmd.args.copySubRes.hasSrcBox = true;
@ -1347,7 +1409,7 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
dxgiFormat = texD->dxgiFormat; dxgiFormat = texD->dxgiFormat;
pixelSize = u.read.rb.level() > 0 ? q->sizeForMipLevel(u.read.rb.level(), texD->m_pixelSize) : texD->m_pixelSize; pixelSize = u.read.rb.level() > 0 ? q->sizeForMipLevel(u.read.rb.level(), texD->m_pixelSize) : texD->m_pixelSize;
format = texD->m_format; format = texD->m_format;
subres = D3D11CalcSubresource(u.read.rb.level(), u.read.rb.layer(), texD->mipLevelCount); subres = D3D11CalcSubresource(UINT(u.read.rb.level()), UINT(u.read.rb.layer()), texD->mipLevelCount);
} else { } else {
Q_ASSERT(contextState.currentSwapChain); Q_ASSERT(contextState.currentSwapChain);
swapChainD = QRHI_RES(QD3D11SwapChain, contextState.currentSwapChain); swapChainD = QRHI_RES(QD3D11SwapChain, contextState.currentSwapChain);
@ -1376,8 +1438,8 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
D3D11_TEXTURE2D_DESC desc; D3D11_TEXTURE2D_DESC desc;
memset(&desc, 0, sizeof(desc)); memset(&desc, 0, sizeof(desc));
desc.Width = pixelSize.width(); desc.Width = UINT(pixelSize.width());
desc.Height = pixelSize.height(); desc.Height = UINT(pixelSize.height());
desc.MipLevels = 1; desc.MipLevels = 1;
desc.ArraySize = 1; desc.ArraySize = 1;
desc.Format = dxgiFormat; desc.Format = dxgiFormat;
@ -1390,7 +1452,7 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
qWarning("Failed to create readback staging texture: %s", qPrintable(comErrorMessage(hr))); qWarning("Failed to create readback staging texture: %s", qPrintable(comErrorMessage(hr)));
return; return;
} }
QRHI_PROF_F(newReadbackBuffer(quint64(quintptr(stagingTex)), QRHI_PROF_F(newReadbackBuffer(qint64(qintptr(stagingTex)),
texD ? static_cast<QRhiResource *>(texD) : static_cast<QRhiResource *>(swapChainD), texD ? static_cast<QRhiResource *>(texD) : static_cast<QRhiResource *>(swapChainD),
bufSize)); bufSize));
@ -1433,7 +1495,7 @@ void QRhiD3D11::finishActiveReadbacks()
const QRhiD3D11::ActiveReadback &aRb(activeReadbacks[i]); const QRhiD3D11::ActiveReadback &aRb(activeReadbacks[i]);
aRb.result->format = aRb.format; aRb.result->format = aRb.format;
aRb.result->pixelSize = aRb.pixelSize; aRb.result->pixelSize = aRb.pixelSize;
aRb.result->data.resize(aRb.bufSize); aRb.result->data.resize(int(aRb.bufSize));
D3D11_MAPPED_SUBRESOURCE mp; D3D11_MAPPED_SUBRESOURCE mp;
HRESULT hr = context->Map(aRb.stagingTex, 0, D3D11_MAP_READ, 0, &mp); HRESULT hr = context->Map(aRb.stagingTex, 0, D3D11_MAP_READ, 0, &mp);
@ -1454,7 +1516,7 @@ void QRhiD3D11::finishActiveReadbacks()
context->Unmap(aRb.stagingTex, 0); context->Unmap(aRb.stagingTex, 0);
aRb.stagingTex->Release(); aRb.stagingTex->Release();
QRHI_PROF_F(releaseReadbackBuffer(quint64(quintptr(aRb.stagingTex)))); QRHI_PROF_F(releaseReadbackBuffer(qint64(qintptr(aRb.stagingTex))));
if (aRb.result->completed) if (aRb.result->completed)
completedCallbacks.append(aRb.result->completed); completedCallbacks.append(aRb.result->completed);
@ -1523,10 +1585,10 @@ void QRhiD3D11::beginPass(QRhiCommandBuffer *cb,
if (rtD->dsAttCount && wantsDsClear) if (rtD->dsAttCount && wantsDsClear)
clearCmd.args.clear.mask |= QD3D11CommandBuffer::Command::Depth | QD3D11CommandBuffer::Command::Stencil; clearCmd.args.clear.mask |= QD3D11CommandBuffer::Command::Depth | QD3D11CommandBuffer::Command::Stencil;
clearCmd.args.clear.c[0] = colorClearValue.redF(); clearCmd.args.clear.c[0] = float(colorClearValue.redF());
clearCmd.args.clear.c[1] = colorClearValue.greenF(); clearCmd.args.clear.c[1] = float(colorClearValue.greenF());
clearCmd.args.clear.c[2] = colorClearValue.blueF(); clearCmd.args.clear.c[2] = float(colorClearValue.blueF());
clearCmd.args.clear.c[3] = colorClearValue.alphaF(); clearCmd.args.clear.c[3] = float(colorClearValue.alphaF());
clearCmd.args.clear.d = depthStencilClearValue.depthClearValue(); clearCmd.args.clear.d = depthStencilClearValue.depthClearValue();
clearCmd.args.clear.s = depthStencilClearValue.stencilClearValue(); clearCmd.args.clear.s = depthStencilClearValue.stencilClearValue();
cbD->commands.append(clearCmd); cbD->commands.append(clearCmd);
@ -1557,8 +1619,8 @@ void QRhiD3D11::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resource
QD3D11CommandBuffer::Command cmd; QD3D11CommandBuffer::Command cmd;
cmd.cmd = QD3D11CommandBuffer::Command::ResolveSubRes; cmd.cmd = QD3D11CommandBuffer::Command::ResolveSubRes;
cmd.args.resolveSubRes.dst = dstTexD->tex; cmd.args.resolveSubRes.dst = dstTexD->tex;
cmd.args.resolveSubRes.dstSubRes = D3D11CalcSubresource(colorAtt.resolveLevel(), cmd.args.resolveSubRes.dstSubRes = D3D11CalcSubresource(UINT(colorAtt.resolveLevel()),
colorAtt.resolveLayer(), UINT(colorAtt.resolveLayer()),
dstTexD->mipLevelCount); dstTexD->mipLevelCount);
if (srcTexD) { if (srcTexD) {
cmd.args.resolveSubRes.src = srcTexD->tex; cmd.args.resolveSubRes.src = srcTexD->tex;
@ -1585,7 +1647,7 @@ void QRhiD3D11::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resource
continue; continue;
} }
} }
cmd.args.resolveSubRes.srcSubRes = D3D11CalcSubresource(0, colorAtt.layer(), 1); cmd.args.resolveSubRes.srcSubRes = D3D11CalcSubresource(0, UINT(colorAtt.layer()), 1);
cmd.args.resolveSubRes.format = dstTexD->dxgiFormat; cmd.args.resolveSubRes.format = dstTexD->dxgiFormat;
cbD->commands.append(cmd); cbD->commands.append(cmd);
} }
@ -1652,9 +1714,9 @@ void QRhiD3D11::dispatch(QRhiCommandBuffer *cb, int x, int y, int z)
QD3D11CommandBuffer::Command cmd; QD3D11CommandBuffer::Command cmd;
cmd.cmd = QD3D11CommandBuffer::Command::Dispatch; cmd.cmd = QD3D11CommandBuffer::Command::Dispatch;
cmd.args.dispatch.x = x; cmd.args.dispatch.x = UINT(x);
cmd.args.dispatch.y = y; cmd.args.dispatch.y = UINT(y);
cmd.args.dispatch.z = z; cmd.args.dispatch.z = UINT(z);
cbD->commands.append(cmd); cbD->commands.append(cmd);
} }
@ -1696,11 +1758,11 @@ void QRhiD3D11::updateShaderResourceBindings(QD3D11ShaderResourceBindings *srbD)
// dynamic ubuf offsets are not considered here, those are baked in // dynamic ubuf offsets are not considered here, those are baked in
// at a later stage, which is good as vsubufoffsets and friends are // at a later stage, which is good as vsubufoffsets and friends are
// per-srb, not per-setShaderResources call // per-srb, not per-setShaderResources call
const uint offsetInConstants = b->u.ubuf.offset / 16; const uint offsetInConstants = uint(b->u.ubuf.offset) / 16;
// size must be 16 mult. (in constants, i.e. multiple of 256 bytes). // size must be 16 mult. (in constants, i.e. multiple of 256 bytes).
// We can round up if needed since the buffers's actual size // We can round up if needed since the buffers's actual size
// (ByteWidth) is always a multiple of 256. // (ByteWidth) is always a multiple of 256.
const uint sizeInConstants = aligned(b->u.ubuf.maybeSize ? b->u.ubuf.maybeSize : bufD->m_size, 256) / 16; const uint sizeInConstants = uint(aligned(b->u.ubuf.maybeSize ? b->u.ubuf.maybeSize : bufD->m_size, 256) / 16);
if (b->stage.testFlag(QRhiShaderResourceBinding::VertexStage)) { if (b->stage.testFlag(QRhiShaderResourceBinding::VertexStage)) {
srbD->vsubufs.feed(b->binding, bufD->buffer); srbD->vsubufs.feed(b->binding, bufD->buffer);
srbD->vsubufoffsets.feed(b->binding, offsetInConstants); srbD->vsubufoffsets.feed(b->binding, offsetInConstants);
@ -1818,7 +1880,7 @@ void QRhiD3D11::executeBufferHostWritesForCurrentFrame(QD3D11Buffer *bufD)
D3D11_MAPPED_SUBRESOURCE mp; D3D11_MAPPED_SUBRESOURCE mp;
HRESULT hr = context->Map(bufD->buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mp); HRESULT hr = context->Map(bufD->buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mp);
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
memcpy(mp.pData, bufD->dynBuf.constData(), bufD->dynBuf.size()); memcpy(mp.pData, bufD->dynBuf.constData(), size_t(bufD->dynBuf.size()));
context->Unmap(bufD->buffer, 0); context->Unmap(bufD->buffer, 0);
} else { } else {
qWarning("Failed to map buffer: %s", qPrintable(comErrorMessage(hr))); qWarning("Failed to map buffer: %s", qPrintable(comErrorMessage(hr)));
@ -1831,13 +1893,13 @@ static void applyDynamicOffsets(QVarLengthArray<UINT, 4> *offsets,
QRhiBatchedBindings<UINT> *ubufoffsets, QRhiBatchedBindings<UINT> *ubufoffsets,
const uint *dynOfsPairs, int dynOfsPairCount) const uint *dynOfsPairs, int dynOfsPairCount)
{ {
const UINT count = ubufs->batches[batchIndex].resources.count(); const int count = ubufs->batches[batchIndex].resources.count();
const UINT startBinding = ubufs->batches[batchIndex].startBinding; const UINT startBinding = ubufs->batches[batchIndex].startBinding;
*offsets = ubufoffsets->batches[batchIndex].resources; *offsets = ubufoffsets->batches[batchIndex].resources;
for (UINT b = 0; b < count; ++b) { for (int b = 0; b < count; ++b) {
for (int di = 0; di < dynOfsPairCount; ++di) { for (int di = 0; di < dynOfsPairCount; ++di) {
const uint binding = dynOfsPairs[2 * di]; const uint binding = dynOfsPairs[2 * di];
if (binding == startBinding + b) { if (binding == startBinding + UINT(b)) {
const uint offsetInConstants = dynOfsPairs[2 * di + 1]; const uint offsetInConstants = dynOfsPairs[2 * di + 1];
(*offsets)[b] = offsetInConstants; (*offsets)[b] = offsetInConstants;
break; break;
@ -1852,37 +1914,37 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
{ {
if (!offsetOnlyChange) { if (!offsetOnlyChange) {
for (const auto &batch : srbD->vssamplers.batches) for (const auto &batch : srbD->vssamplers.batches)
context->VSSetSamplers(batch.startBinding, batch.resources.count(), batch.resources.constData()); context->VSSetSamplers(batch.startBinding, UINT(batch.resources.count()), batch.resources.constData());
for (const auto &batch : srbD->vsshaderresources.batches) { for (const auto &batch : srbD->vsshaderresources.batches) {
context->VSSetShaderResources(batch.startBinding, batch.resources.count(), batch.resources.constData()); context->VSSetShaderResources(batch.startBinding, UINT(batch.resources.count()), batch.resources.constData());
contextState.vsHighestActiveSrvBinding = qMax<int>(contextState.vsHighestActiveSrvBinding, contextState.vsHighestActiveSrvBinding = qMax<int>(contextState.vsHighestActiveSrvBinding,
batch.startBinding + batch.resources.count() - 1); int(batch.startBinding) + batch.resources.count() - 1);
} }
for (const auto &batch : srbD->fssamplers.batches) for (const auto &batch : srbD->fssamplers.batches)
context->PSSetSamplers(batch.startBinding, batch.resources.count(), batch.resources.constData()); context->PSSetSamplers(batch.startBinding, UINT(batch.resources.count()), batch.resources.constData());
for (const auto &batch : srbD->fsshaderresources.batches) { for (const auto &batch : srbD->fsshaderresources.batches) {
context->PSSetShaderResources(batch.startBinding, batch.resources.count(), batch.resources.constData()); context->PSSetShaderResources(batch.startBinding, UINT(batch.resources.count()), batch.resources.constData());
contextState.fsHighestActiveSrvBinding = qMax<int>(contextState.fsHighestActiveSrvBinding, contextState.fsHighestActiveSrvBinding = qMax<int>(contextState.fsHighestActiveSrvBinding,
batch.startBinding + batch.resources.count() - 1); int(batch.startBinding) + batch.resources.count() - 1);
} }
for (const auto &batch : srbD->cssamplers.batches) for (const auto &batch : srbD->cssamplers.batches)
context->CSSetSamplers(batch.startBinding, batch.resources.count(), batch.resources.constData()); context->CSSetSamplers(batch.startBinding, UINT(batch.resources.count()), batch.resources.constData());
for (const auto &batch : srbD->csshaderresources.batches) { for (const auto &batch : srbD->csshaderresources.batches) {
context->CSSetShaderResources(batch.startBinding, batch.resources.count(), batch.resources.constData()); context->CSSetShaderResources(batch.startBinding, UINT(batch.resources.count()), batch.resources.constData());
contextState.csHighestActiveSrvBinding = qMax<int>(contextState.csHighestActiveSrvBinding, contextState.csHighestActiveSrvBinding = qMax<int>(contextState.csHighestActiveSrvBinding,
batch.startBinding + batch.resources.count() - 1); int(batch.startBinding) + batch.resources.count() - 1);
} }
} }
for (int i = 0, ie = srbD->vsubufs.batches.count(); i != ie; ++i) { for (int i = 0, ie = srbD->vsubufs.batches.count(); i != ie; ++i) {
if (!dynOfsPairCount) { if (!dynOfsPairCount) {
context->VSSetConstantBuffers1(srbD->vsubufs.batches[i].startBinding, context->VSSetConstantBuffers1(srbD->vsubufs.batches[i].startBinding,
srbD->vsubufs.batches[i].resources.count(), UINT(srbD->vsubufs.batches[i].resources.count()),
srbD->vsubufs.batches[i].resources.constData(), srbD->vsubufs.batches[i].resources.constData(),
srbD->vsubufoffsets.batches[i].resources.constData(), srbD->vsubufoffsets.batches[i].resources.constData(),
srbD->vsubufsizes.batches[i].resources.constData()); srbD->vsubufsizes.batches[i].resources.constData());
@ -1890,7 +1952,7 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
QVarLengthArray<UINT, 4> offsets; QVarLengthArray<UINT, 4> offsets;
applyDynamicOffsets(&offsets, i, &srbD->vsubufs, &srbD->vsubufoffsets, dynOfsPairs, dynOfsPairCount); applyDynamicOffsets(&offsets, i, &srbD->vsubufs, &srbD->vsubufoffsets, dynOfsPairs, dynOfsPairCount);
context->VSSetConstantBuffers1(srbD->vsubufs.batches[i].startBinding, context->VSSetConstantBuffers1(srbD->vsubufs.batches[i].startBinding,
srbD->vsubufs.batches[i].resources.count(), UINT(srbD->vsubufs.batches[i].resources.count()),
srbD->vsubufs.batches[i].resources.constData(), srbD->vsubufs.batches[i].resources.constData(),
offsets.constData(), offsets.constData(),
srbD->vsubufsizes.batches[i].resources.constData()); srbD->vsubufsizes.batches[i].resources.constData());
@ -1900,7 +1962,7 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
for (int i = 0, ie = srbD->fsubufs.batches.count(); i != ie; ++i) { for (int i = 0, ie = srbD->fsubufs.batches.count(); i != ie; ++i) {
if (!dynOfsPairCount) { if (!dynOfsPairCount) {
context->PSSetConstantBuffers1(srbD->fsubufs.batches[i].startBinding, context->PSSetConstantBuffers1(srbD->fsubufs.batches[i].startBinding,
srbD->fsubufs.batches[i].resources.count(), UINT(srbD->fsubufs.batches[i].resources.count()),
srbD->fsubufs.batches[i].resources.constData(), srbD->fsubufs.batches[i].resources.constData(),
srbD->fsubufoffsets.batches[i].resources.constData(), srbD->fsubufoffsets.batches[i].resources.constData(),
srbD->fsubufsizes.batches[i].resources.constData()); srbD->fsubufsizes.batches[i].resources.constData());
@ -1908,7 +1970,7 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
QVarLengthArray<UINT, 4> offsets; QVarLengthArray<UINT, 4> offsets;
applyDynamicOffsets(&offsets, i, &srbD->fsubufs, &srbD->fsubufoffsets, dynOfsPairs, dynOfsPairCount); applyDynamicOffsets(&offsets, i, &srbD->fsubufs, &srbD->fsubufoffsets, dynOfsPairs, dynOfsPairCount);
context->PSSetConstantBuffers1(srbD->fsubufs.batches[i].startBinding, context->PSSetConstantBuffers1(srbD->fsubufs.batches[i].startBinding,
srbD->fsubufs.batches[i].resources.count(), UINT(srbD->fsubufs.batches[i].resources.count()),
srbD->fsubufs.batches[i].resources.constData(), srbD->fsubufs.batches[i].resources.constData(),
offsets.constData(), offsets.constData(),
srbD->fsubufsizes.batches[i].resources.constData()); srbD->fsubufsizes.batches[i].resources.constData());
@ -1918,7 +1980,7 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
for (int i = 0, ie = srbD->csubufs.batches.count(); i != ie; ++i) { for (int i = 0, ie = srbD->csubufs.batches.count(); i != ie; ++i) {
if (!dynOfsPairCount) { if (!dynOfsPairCount) {
context->CSSetConstantBuffers1(srbD->csubufs.batches[i].startBinding, context->CSSetConstantBuffers1(srbD->csubufs.batches[i].startBinding,
srbD->csubufs.batches[i].resources.count(), UINT(srbD->csubufs.batches[i].resources.count()),
srbD->csubufs.batches[i].resources.constData(), srbD->csubufs.batches[i].resources.constData(),
srbD->csubufoffsets.batches[i].resources.constData(), srbD->csubufoffsets.batches[i].resources.constData(),
srbD->csubufsizes.batches[i].resources.constData()); srbD->csubufsizes.batches[i].resources.constData());
@ -1926,7 +1988,7 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
QVarLengthArray<UINT, 4> offsets; QVarLengthArray<UINT, 4> offsets;
applyDynamicOffsets(&offsets, i, &srbD->csubufs, &srbD->csubufoffsets, dynOfsPairs, dynOfsPairCount); applyDynamicOffsets(&offsets, i, &srbD->csubufs, &srbD->csubufoffsets, dynOfsPairs, dynOfsPairCount);
context->CSSetConstantBuffers1(srbD->csubufs.batches[i].startBinding, context->CSSetConstantBuffers1(srbD->csubufs.batches[i].startBinding,
srbD->csubufs.batches[i].resources.count(), UINT(srbD->csubufs.batches[i].resources.count()),
srbD->csubufs.batches[i].resources.constData(), srbD->csubufs.batches[i].resources.constData(),
offsets.constData(), offsets.constData(),
srbD->csubufsizes.batches[i].resources.constData()); srbD->csubufsizes.batches[i].resources.constData());
@ -1935,13 +1997,13 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
for (int i = 0, ie = srbD->csUAVs.batches.count(); i != ie; ++i) { for (int i = 0, ie = srbD->csUAVs.batches.count(); i != ie; ++i) {
const uint startBinding = srbD->csUAVs.batches[i].startBinding; const uint startBinding = srbD->csUAVs.batches[i].startBinding;
const uint count = srbD->csUAVs.batches[i].resources.count(); const uint count = uint(srbD->csUAVs.batches[i].resources.count());
context->CSSetUnorderedAccessViews(startBinding, context->CSSetUnorderedAccessViews(startBinding,
count, count,
srbD->csUAVs.batches[i].resources.constData(), srbD->csUAVs.batches[i].resources.constData(),
nullptr); nullptr);
contextState.csHighestActiveUavBinding = qMax<int>(contextState.csHighestActiveUavBinding, contextState.csHighestActiveUavBinding = qMax<int>(contextState.csHighestActiveUavBinding,
startBinding + count - 1); int(startBinding + count - 1));
} }
} }
@ -1965,7 +2027,7 @@ void QRhiD3D11::resetShaderResources()
QVarLengthArray<UINT, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT> nulloffsets(count); QVarLengthArray<UINT, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT> nulloffsets(count);
for (int i = 0; i < count; ++i) for (int i = 0; i < count; ++i)
nulloffsets[i] = 0; nulloffsets[i] = 0;
context->IASetVertexBuffers(0, count, nullbufs.constData(), nullstrides.constData(), nulloffsets.constData()); context->IASetVertexBuffers(0, UINT(count), nullbufs.constData(), nullstrides.constData(), nulloffsets.constData());
contextState.vsHighestActiveVertexBufferBinding = -1; contextState.vsHighestActiveVertexBufferBinding = -1;
} }
@ -1978,15 +2040,15 @@ void QRhiD3D11::resetShaderResources()
for (int i = 0; i < nullsrvs.count(); ++i) for (int i = 0; i < nullsrvs.count(); ++i)
nullsrvs[i] = nullptr; nullsrvs[i] = nullptr;
if (contextState.vsHighestActiveSrvBinding >= 0) { if (contextState.vsHighestActiveSrvBinding >= 0) {
context->VSSetShaderResources(0, contextState.vsHighestActiveSrvBinding + 1, nullsrvs.constData()); context->VSSetShaderResources(0, UINT(contextState.vsHighestActiveSrvBinding + 1), nullsrvs.constData());
contextState.vsHighestActiveSrvBinding = -1; contextState.vsHighestActiveSrvBinding = -1;
} }
if (contextState.fsHighestActiveSrvBinding >= 0) { if (contextState.fsHighestActiveSrvBinding >= 0) {
context->PSSetShaderResources(0, contextState.fsHighestActiveSrvBinding + 1, nullsrvs.constData()); context->PSSetShaderResources(0, UINT(contextState.fsHighestActiveSrvBinding + 1), nullsrvs.constData());
contextState.fsHighestActiveSrvBinding = -1; contextState.fsHighestActiveSrvBinding = -1;
} }
if (contextState.csHighestActiveSrvBinding >= 0) { if (contextState.csHighestActiveSrvBinding >= 0) {
context->CSSetShaderResources(0, contextState.csHighestActiveSrvBinding + 1, nullsrvs.constData()); context->CSSetShaderResources(0, UINT(contextState.csHighestActiveSrvBinding + 1), nullsrvs.constData());
contextState.csHighestActiveSrvBinding = -1; contextState.csHighestActiveSrvBinding = -1;
} }
} }
@ -1997,7 +2059,7 @@ void QRhiD3D11::resetShaderResources()
D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT> nulluavs(nulluavCount); D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT> nulluavs(nulluavCount);
for (int i = 0; i < nulluavCount; ++i) for (int i = 0; i < nulluavCount; ++i)
nulluavs[i] = nullptr; nulluavs[i] = nullptr;
context->CSSetUnorderedAccessViews(0, nulluavCount, nulluavs.constData(), nullptr); context->CSSetUnorderedAccessViews(0, UINT(nulluavCount), nulluavs.constData(), nullptr);
contextState.csHighestActiveUavBinding = -1; contextState.csHighestActiveUavBinding = -1;
} }
} }
@ -2019,7 +2081,7 @@ void QRhiD3D11::executeCommandBuffer(QD3D11CommandBuffer *cbD, QD3D11SwapChain *
// writing the first timestamp only afterwards. // writing the first timestamp only afterwards.
context->Begin(tsDisjoint); context->Begin(tsDisjoint);
QD3D11RenderTargetData *rtD = rtData(&timestampSwapChain->rt); QD3D11RenderTargetData *rtD = rtData(&timestampSwapChain->rt);
context->OMSetRenderTargets(rtD->colorAttCount, rtD->colorAttCount ? rtD->rtv : nullptr, rtD->dsv); context->OMSetRenderTargets(UINT(rtD->colorAttCount), rtD->colorAttCount ? rtD->rtv : nullptr, rtD->dsv);
context->End(tsStart); // just record a timestamp, no Begin needed context->End(tsStart); // just record a timestamp, no Begin needed
} }
} }
@ -2032,7 +2094,7 @@ void QRhiD3D11::executeCommandBuffer(QD3D11CommandBuffer *cbD, QD3D11SwapChain *
case QD3D11CommandBuffer::Command::SetRenderTarget: case QD3D11CommandBuffer::Command::SetRenderTarget:
{ {
QD3D11RenderTargetData *rtD = rtData(cmd.args.setRenderTarget.rt); QD3D11RenderTargetData *rtD = rtData(cmd.args.setRenderTarget.rt);
context->OMSetRenderTargets(rtD->colorAttCount, rtD->colorAttCount ? rtD->rtv : nullptr, rtD->dsv); context->OMSetRenderTargets(UINT(rtD->colorAttCount), rtD->colorAttCount ? rtD->rtv : nullptr, rtD->dsv);
} }
break; break;
case QD3D11CommandBuffer::Command::Clear: case QD3D11CommandBuffer::Command::Clear:
@ -2048,7 +2110,7 @@ void QRhiD3D11::executeCommandBuffer(QD3D11CommandBuffer *cbD, QD3D11SwapChain *
if (cmd.args.clear.mask & QD3D11CommandBuffer::Command::Stencil) if (cmd.args.clear.mask & QD3D11CommandBuffer::Command::Stencil)
ds |= D3D11_CLEAR_STENCIL; ds |= D3D11_CLEAR_STENCIL;
if (ds) if (ds)
context->ClearDepthStencilView(rtD->dsv, ds, cmd.args.clear.d, cmd.args.clear.s); context->ClearDepthStencilView(rtD->dsv, ds, cmd.args.clear.d, UINT8(cmd.args.clear.s));
} }
break; break;
case QD3D11CommandBuffer::Command::Viewport: case QD3D11CommandBuffer::Command::Viewport:
@ -2078,8 +2140,8 @@ void QRhiD3D11::executeCommandBuffer(QD3D11CommandBuffer *cbD, QD3D11SwapChain *
contextState.vsHighestActiveVertexBufferBinding = qMax<int>( contextState.vsHighestActiveVertexBufferBinding = qMax<int>(
contextState.vsHighestActiveVertexBufferBinding, contextState.vsHighestActiveVertexBufferBinding,
cmd.args.bindVertexBuffers.startSlot + cmd.args.bindVertexBuffers.slotCount - 1); cmd.args.bindVertexBuffers.startSlot + cmd.args.bindVertexBuffers.slotCount - 1);
context->IASetVertexBuffers(cmd.args.bindVertexBuffers.startSlot, context->IASetVertexBuffers(UINT(cmd.args.bindVertexBuffers.startSlot),
cmd.args.bindVertexBuffers.slotCount, UINT(cmd.args.bindVertexBuffers.slotCount),
cmd.args.bindVertexBuffers.buffers, cmd.args.bindVertexBuffers.buffers,
cmd.args.bindVertexBuffers.strides, cmd.args.bindVertexBuffers.strides,
cmd.args.bindVertexBuffers.offsets); cmd.args.bindVertexBuffers.offsets);
@ -2222,7 +2284,7 @@ static inline uint toD3DBufferUsage(QRhiBuffer::UsageFlags usage)
u |= D3D11_BIND_CONSTANT_BUFFER; u |= D3D11_BIND_CONSTANT_BUFFER;
if (usage.testFlag(QRhiBuffer::StorageBuffer)) if (usage.testFlag(QRhiBuffer::StorageBuffer))
u |= D3D11_BIND_UNORDERED_ACCESS; u |= D3D11_BIND_UNORDERED_ACCESS;
return u; return uint(u);
} }
bool QD3D11Buffer::build() bool QD3D11Buffer::build()
@ -2245,7 +2307,7 @@ bool QD3D11Buffer::build()
D3D11_BUFFER_DESC desc; D3D11_BUFFER_DESC desc;
memset(&desc, 0, sizeof(desc)); memset(&desc, 0, sizeof(desc));
desc.ByteWidth = roundedSize; desc.ByteWidth = UINT(roundedSize);
desc.Usage = m_type == Dynamic ? D3D11_USAGE_DYNAMIC : D3D11_USAGE_DEFAULT; desc.Usage = m_type == Dynamic ? D3D11_USAGE_DYNAMIC : D3D11_USAGE_DEFAULT;
desc.BindFlags = toD3DBufferUsage(m_usage); desc.BindFlags = toD3DBufferUsage(m_usage);
desc.CPUAccessFlags = m_type == Dynamic ? D3D11_CPU_ACCESS_WRITE : 0; desc.CPUAccessFlags = m_type == Dynamic ? D3D11_CPU_ACCESS_WRITE : 0;
@ -2264,10 +2326,10 @@ bool QD3D11Buffer::build()
} }
if (!m_objectName.isEmpty()) if (!m_objectName.isEmpty())
buffer->SetPrivateData(WKPDID_D3DDebugObjectName, m_objectName.size(), m_objectName.constData()); buffer->SetPrivateData(WKPDID_D3DDebugObjectName, UINT(m_objectName.size()), m_objectName.constData());
QRHI_PROF; QRHI_PROF;
QRHI_PROF_F(newBuffer(this, roundedSize, m_type == Dynamic ? 2 : 1, m_type == Dynamic ? 1 : 0)); QRHI_PROF_F(newBuffer(this, quint32(roundedSize), m_type == Dynamic ? 2 : 1, m_type == Dynamic ? 1 : 0));
generation += 1; generation += 1;
rhiD->registerResource(this); rhiD->registerResource(this);
@ -2285,7 +2347,7 @@ ID3D11UnorderedAccessView *QD3D11Buffer::unorderedAccessView()
desc.Format = DXGI_FORMAT_R32_TYPELESS; desc.Format = DXGI_FORMAT_R32_TYPELESS;
desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
desc.Buffer.FirstElement = 0; desc.Buffer.FirstElement = 0;
desc.Buffer.NumElements = aligned(m_size, 4) / 4; desc.Buffer.NumElements = UINT(aligned(m_size, 4) / 4);
desc.Buffer.Flags = D3D11_BUFFER_UAV_FLAG_RAW; desc.Buffer.Flags = D3D11_BUFFER_UAV_FLAG_RAW;
QRHI_RES_RHI(QRhiD3D11); QRHI_RES_RHI(QRhiD3D11);
@ -2346,8 +2408,8 @@ bool QD3D11RenderBuffer::build()
D3D11_TEXTURE2D_DESC desc; D3D11_TEXTURE2D_DESC desc;
memset(&desc, 0, sizeof(desc)); memset(&desc, 0, sizeof(desc));
desc.Width = m_pixelSize.width(); desc.Width = UINT(m_pixelSize.width());
desc.Height = m_pixelSize.height(); desc.Height = UINT(m_pixelSize.height());
desc.MipLevels = 1; desc.MipLevels = 1;
desc.ArraySize = 1; desc.ArraySize = 1;
desc.SampleDesc = sampleDesc; desc.SampleDesc = sampleDesc;
@ -2396,10 +2458,10 @@ bool QD3D11RenderBuffer::build()
} }
if (!m_objectName.isEmpty()) if (!m_objectName.isEmpty())
tex->SetPrivateData(WKPDID_D3DDebugObjectName, m_objectName.size(), m_objectName.constData()); tex->SetPrivateData(WKPDID_D3DDebugObjectName, UINT(m_objectName.size()), m_objectName.constData());
QRHI_PROF; QRHI_PROF;
QRHI_PROF_F(newRenderBuffer(this, false, false, sampleDesc.Count)); QRHI_PROF_F(newRenderBuffer(this, false, false, int(sampleDesc.Count)));
rhiD->registerResource(this); rhiD->registerResource(this);
return true; return true;
@ -2489,7 +2551,7 @@ bool QD3D11Texture::prepareBuild(QSize *adjustedSize)
QRHI_RES_RHI(QRhiD3D11); QRHI_RES_RHI(QRhiD3D11);
dxgiFormat = toD3DTextureFormat(m_format, m_flags); dxgiFormat = toD3DTextureFormat(m_format, m_flags);
mipLevelCount = hasMipMaps ? rhiD->q->mipLevelsForSize(size) : 1; mipLevelCount = uint(hasMipMaps ? rhiD->q->mipLevelsForSize(size) : 1);
sampleDesc = rhiD->effectiveSampleCount(m_sampleCount); sampleDesc = rhiD->effectiveSampleCount(m_sampleCount);
if (sampleDesc.Count > 1) { if (sampleDesc.Count > 1) {
if (isCube) { if (isCube) {
@ -2575,8 +2637,8 @@ bool QD3D11Texture::build()
D3D11_TEXTURE2D_DESC desc; D3D11_TEXTURE2D_DESC desc;
memset(&desc, 0, sizeof(desc)); memset(&desc, 0, sizeof(desc));
desc.Width = size.width(); desc.Width = UINT(size.width());
desc.Height = size.height(); desc.Height = UINT(size.height());
desc.MipLevels = mipLevelCount; desc.MipLevels = mipLevelCount;
desc.ArraySize = isCube ? 6 : 1; desc.ArraySize = isCube ? 6 : 1;
desc.Format = dxgiFormat; desc.Format = dxgiFormat;
@ -2596,10 +2658,10 @@ bool QD3D11Texture::build()
return false; return false;
if (!m_objectName.isEmpty()) if (!m_objectName.isEmpty())
tex->SetPrivateData(WKPDID_D3DDebugObjectName, m_objectName.size(), m_objectName.constData()); tex->SetPrivateData(WKPDID_D3DDebugObjectName, UINT(m_objectName.size()), m_objectName.constData());
QRHI_PROF; QRHI_PROF;
QRHI_PROF_F(newTexture(this, true, mipLevelCount, isCube ? 6 : 1, sampleDesc.Count)); QRHI_PROF_F(newTexture(this, true, int(mipLevelCount), isCube ? 6 : 1, int(sampleDesc.Count)));
owns = true; owns = true;
rhiD->registerResource(this); rhiD->registerResource(this);
@ -2621,7 +2683,7 @@ bool QD3D11Texture::buildFrom(const QRhiNativeHandles *src)
return false; return false;
QRHI_PROF; QRHI_PROF;
QRHI_PROF_F(newTexture(this, false, mipLevelCount, m_flags.testFlag(CubeMap) ? 6 : 1, sampleDesc.Count)); QRHI_PROF_F(newTexture(this, false, int(mipLevelCount), m_flags.testFlag(CubeMap) ? 6 : 1, int(sampleDesc.Count)));
owns = false; owns = false;
QRHI_RES_RHI(QRhiD3D11); QRHI_RES_RHI(QRhiD3D11);
@ -2645,12 +2707,12 @@ ID3D11UnorderedAccessView *QD3D11Texture::unorderedAccessViewForLevel(int level)
desc.Format = dxgiFormat; desc.Format = dxgiFormat;
if (isCube) { if (isCube) {
desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY; desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY;
desc.Texture2DArray.MipSlice = level; desc.Texture2DArray.MipSlice = UINT(level);
desc.Texture2DArray.FirstArraySlice = 0; desc.Texture2DArray.FirstArraySlice = 0;
desc.Texture2DArray.ArraySize = 6; desc.Texture2DArray.ArraySize = 6;
} else { } else {
desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D; desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
desc.Texture2D.MipSlice = level; desc.Texture2D.MipSlice = UINT(level);
} }
QRHI_RES_RHI(QRhiD3D11); QRHI_RES_RHI(QRhiD3D11);
@ -2910,15 +2972,15 @@ bool QD3D11TextureRenderTarget::build()
rtvDesc.Format = toD3DTextureFormat(texD->format(), texD->flags()); rtvDesc.Format = toD3DTextureFormat(texD->format(), texD->flags());
if (texD->flags().testFlag(QRhiTexture::CubeMap)) { if (texD->flags().testFlag(QRhiTexture::CubeMap)) {
rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
rtvDesc.Texture2DArray.MipSlice = colorAttachments[i].level(); rtvDesc.Texture2DArray.MipSlice = UINT(colorAttachments[i].level());
rtvDesc.Texture2DArray.FirstArraySlice = colorAttachments[i].layer(); rtvDesc.Texture2DArray.FirstArraySlice = UINT(colorAttachments[i].layer());
rtvDesc.Texture2DArray.ArraySize = 1; rtvDesc.Texture2DArray.ArraySize = 1;
} else { } else {
if (texD->sampleDesc.Count > 1) { if (texD->sampleDesc.Count > 1) {
rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS;
} else { } else {
rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
rtvDesc.Texture2D.MipSlice = colorAttachments[i].level(); rtvDesc.Texture2D.MipSlice = UINT(colorAttachments[i].level());
} }
} }
HRESULT hr = rhiD->dev->CreateRenderTargetView(texD->tex, &rtvDesc, &rtv[i]); HRESULT hr = rhiD->dev->CreateRenderTargetView(texD->tex, &rtvDesc, &rtv[i]);
@ -2929,7 +2991,7 @@ bool QD3D11TextureRenderTarget::build()
ownsRtv[i] = true; ownsRtv[i] = true;
if (i == 0) { if (i == 0) {
d.pixelSize = texD->pixelSize(); d.pixelSize = texD->pixelSize();
d.sampleCount = texD->sampleDesc.Count; d.sampleCount = int(texD->sampleDesc.Count);
} }
} else if (rb) { } else if (rb) {
QD3D11RenderBuffer *rbD = QRHI_RES(QD3D11RenderBuffer, rb); QD3D11RenderBuffer *rbD = QRHI_RES(QD3D11RenderBuffer, rb);
@ -2937,7 +2999,7 @@ bool QD3D11TextureRenderTarget::build()
rtv[i] = rbD->rtv; rtv[i] = rbD->rtv;
if (i == 0) { if (i == 0) {
d.pixelSize = rbD->pixelSize(); d.pixelSize = rbD->pixelSize();
d.sampleCount = rbD->sampleDesc.Count; d.sampleCount = int(rbD->sampleDesc.Count);
} }
} }
} }
@ -2959,7 +3021,7 @@ bool QD3D11TextureRenderTarget::build()
} }
if (d.colorAttCount == 0) { if (d.colorAttCount == 0) {
d.pixelSize = depthTexD->pixelSize(); d.pixelSize = depthTexD->pixelSize();
d.sampleCount = depthTexD->sampleDesc.Count; d.sampleCount = int(depthTexD->sampleDesc.Count);
} }
} else { } else {
ownsDsv = false; ownsDsv = false;
@ -2967,7 +3029,7 @@ bool QD3D11TextureRenderTarget::build()
dsv = depthRbD->dsv; dsv = depthRbD->dsv;
if (d.colorAttCount == 0) { if (d.colorAttCount == 0) {
d.pixelSize = m_desc.depthStencilBuffer()->pixelSize(); d.pixelSize = m_desc.depthStencilBuffer()->pixelSize();
d.sampleCount = depthRbD->sampleDesc.Count; d.sampleCount = int(depthRbD->sampleDesc.Count);
} }
} }
d.dsAttCount = 1; d.dsAttCount = 1;
@ -3191,9 +3253,9 @@ static inline D3D11_PRIMITIVE_TOPOLOGY toD3DTopology(QRhiGraphicsPipeline::Topol
} }
} }
static inline uint toD3DColorWriteMask(QRhiGraphicsPipeline::ColorMask c) static inline UINT8 toD3DColorWriteMask(QRhiGraphicsPipeline::ColorMask c)
{ {
uint f = 0; UINT8 f = 0;
if (c.testFlag(QRhiGraphicsPipeline::R)) if (c.testFlag(QRhiGraphicsPipeline::R))
f |= D3D11_COLOR_WRITE_ENABLE_RED; f |= D3D11_COLOR_WRITE_ENABLE_RED;
if (c.testFlag(QRhiGraphicsPipeline::G)) if (c.testFlag(QRhiGraphicsPipeline::G))
@ -3328,22 +3390,22 @@ static QByteArray compileHlslShaderSource(const QShader &shader, QShader::Varian
ID3DBlob *bytecode = nullptr; ID3DBlob *bytecode = nullptr;
ID3DBlob *errors = nullptr; ID3DBlob *errors = nullptr;
HRESULT hr = d3dCompile(hlslSource.shader().constData(), hlslSource.shader().size(), HRESULT hr = d3dCompile(hlslSource.shader().constData(), SIZE_T(hlslSource.shader().size()),
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
hlslSource.entryPoint().constData(), target, 0, 0, &bytecode, &errors); hlslSource.entryPoint().constData(), target, 0, 0, &bytecode, &errors);
if (FAILED(hr) || !bytecode) { if (FAILED(hr) || !bytecode) {
qWarning("HLSL shader compilation failed: 0x%x", uint(hr)); qWarning("HLSL shader compilation failed: 0x%x", uint(hr));
if (errors) { if (errors) {
*error = QString::fromUtf8(static_cast<const char *>(errors->GetBufferPointer()), *error = QString::fromUtf8(static_cast<const char *>(errors->GetBufferPointer()),
errors->GetBufferSize()); int(errors->GetBufferSize()));
errors->Release(); errors->Release();
} }
return QByteArray(); return QByteArray();
} }
QByteArray result; QByteArray result;
result.resize(bytecode->GetBufferSize()); result.resize(int(bytecode->GetBufferSize()));
memcpy(result.data(), bytecode->GetBufferPointer(), result.size()); memcpy(result.data(), bytecode->GetBufferPointer(), size_t(result.size()));
bytecode->Release(); bytecode->Release();
return result; return result;
} }
@ -3375,8 +3437,8 @@ bool QD3D11GraphicsPipeline::build()
dsDesc.DepthFunc = toD3DCompareOp(m_depthOp); dsDesc.DepthFunc = toD3DCompareOp(m_depthOp);
dsDesc.StencilEnable = m_stencilTest; dsDesc.StencilEnable = m_stencilTest;
if (m_stencilTest) { if (m_stencilTest) {
dsDesc.StencilReadMask = m_stencilReadMask; dsDesc.StencilReadMask = UINT8(m_stencilReadMask);
dsDesc.StencilWriteMask = m_stencilWriteMask; dsDesc.StencilWriteMask = UINT8(m_stencilWriteMask);
dsDesc.FrontFace.StencilFailOp = toD3DStencilOp(m_stencilFront.failOp); dsDesc.FrontFace.StencilFailOp = toD3DStencilOp(m_stencilFront.failOp);
dsDesc.FrontFace.StencilDepthFailOp = toD3DStencilOp(m_stencilFront.depthFailOp); dsDesc.FrontFace.StencilDepthFailOp = toD3DStencilOp(m_stencilFront.depthFailOp);
dsDesc.FrontFace.StencilPassOp = toD3DStencilOp(m_stencilFront.passOp); dsDesc.FrontFace.StencilPassOp = toD3DStencilOp(m_stencilFront.passOp);
@ -3453,7 +3515,7 @@ bool QD3D11GraphicsPipeline::build()
switch (shaderStage.type()) { switch (shaderStage.type()) {
case QRhiShaderStage::Vertex: case QRhiShaderStage::Vertex:
hr = rhiD->dev->CreateVertexShader(bytecode.constData(), bytecode.size(), nullptr, &vs); hr = rhiD->dev->CreateVertexShader(bytecode.constData(), SIZE_T(bytecode.size()), nullptr, &vs);
if (FAILED(hr)) { if (FAILED(hr)) {
qWarning("Failed to create vertex shader: %s", qPrintable(comErrorMessage(hr))); qWarning("Failed to create vertex shader: %s", qPrintable(comErrorMessage(hr)));
return false; return false;
@ -3463,7 +3525,7 @@ bool QD3D11GraphicsPipeline::build()
vs->AddRef(); vs->AddRef();
break; break;
case QRhiShaderStage::Fragment: case QRhiShaderStage::Fragment:
hr = rhiD->dev->CreatePixelShader(bytecode.constData(), bytecode.size(), nullptr, &fs); hr = rhiD->dev->CreatePixelShader(bytecode.constData(), SIZE_T(bytecode.size()), nullptr, &fs);
if (FAILED(hr)) { if (FAILED(hr)) {
qWarning("Failed to create pixel shader: %s", qPrintable(comErrorMessage(hr))); qWarning("Failed to create pixel shader: %s", qPrintable(comErrorMessage(hr)));
return false; return false;
@ -3488,20 +3550,21 @@ bool QD3D11GraphicsPipeline::build()
memset(&desc, 0, sizeof(desc)); memset(&desc, 0, sizeof(desc));
// the output from SPIRV-Cross uses TEXCOORD<location> as the semantic // the output from SPIRV-Cross uses TEXCOORD<location> as the semantic
desc.SemanticName = "TEXCOORD"; desc.SemanticName = "TEXCOORD";
desc.SemanticIndex = attribute.location(); desc.SemanticIndex = UINT(attribute.location());
desc.Format = toD3DAttributeFormat(attribute.format()); desc.Format = toD3DAttributeFormat(attribute.format());
desc.InputSlot = attribute.binding(); desc.InputSlot = UINT(attribute.binding());
desc.AlignedByteOffset = attribute.offset(); desc.AlignedByteOffset = attribute.offset();
const QRhiVertexInputBinding &binding(bindings[attribute.binding()]); const QRhiVertexInputBinding &binding(bindings[attribute.binding()]);
if (binding.classification() == QRhiVertexInputBinding::PerInstance) { if (binding.classification() == QRhiVertexInputBinding::PerInstance) {
desc.InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA; desc.InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA;
desc.InstanceDataStepRate = binding.instanceStepRate(); desc.InstanceDataStepRate = UINT(binding.instanceStepRate());
} else { } else {
desc.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; desc.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
} }
inputDescs.append(desc); inputDescs.append(desc);
} }
hr = rhiD->dev->CreateInputLayout(inputDescs.constData(), inputDescs.count(), vsByteCode, vsByteCode.size(), &inputLayout); hr = rhiD->dev->CreateInputLayout(inputDescs.constData(), UINT(inputDescs.count()),
vsByteCode, SIZE_T(vsByteCode.size()), &inputLayout);
if (FAILED(hr)) { if (FAILED(hr)) {
qWarning("Failed to create input layout: %s", qPrintable(comErrorMessage(hr))); qWarning("Failed to create input layout: %s", qPrintable(comErrorMessage(hr)));
return false; return false;
@ -3554,7 +3617,7 @@ bool QD3D11ComputePipeline::build()
return false; return false;
} }
HRESULT hr = rhiD->dev->CreateComputeShader(bytecode.constData(), bytecode.size(), nullptr, &cs); HRESULT hr = rhiD->dev->CreateComputeShader(bytecode.constData(), SIZE_T(bytecode.size()), nullptr, &cs);
if (FAILED(hr)) { if (FAILED(hr)) {
qWarning("Failed to create compute shader: %s", qPrintable(comErrorMessage(hr))); qWarning("Failed to create compute shader: %s", qPrintable(comErrorMessage(hr)));
return false; return false;
@ -3690,8 +3753,8 @@ bool QD3D11SwapChain::newColorBuffer(const QSize &size, DXGI_FORMAT format, DXGI
{ {
D3D11_TEXTURE2D_DESC desc; D3D11_TEXTURE2D_DESC desc;
memset(&desc, 0, sizeof(desc)); memset(&desc, 0, sizeof(desc));
desc.Width = size.width(); desc.Width = UINT(size.width());
desc.Height = size.height(); desc.Height = UINT(size.height());
desc.MipLevels = 1; desc.MipLevels = 1;
desc.ArraySize = 1; desc.ArraySize = 1;
desc.Format = format; desc.Format = format;
@ -3747,11 +3810,23 @@ bool QD3D11SwapChain::buildOrResize()
const UINT swapChainFlags = 0; const UINT swapChainFlags = 0;
QRHI_RES_RHI(QRhiD3D11); QRHI_RES_RHI(QRhiD3D11);
const bool useFlipDiscard = rhiD->hasDxgi2 && rhiD->supportsFlipDiscardSwapchain; bool useFlipDiscard = rhiD->hasDxgi2 && rhiD->supportsFlipDiscardSwapchain;
if (!swapChain) { if (!swapChain) {
HWND hwnd = reinterpret_cast<HWND>(window->winId()); HWND hwnd = reinterpret_cast<HWND>(window->winId());
sampleDesc = rhiD->effectiveSampleCount(m_sampleCount); sampleDesc = rhiD->effectiveSampleCount(m_sampleCount);
// Take a shortcut for alpha: our QWindow is OpenGLSurface so whatever
// the platform plugin does to enable transparency for OpenGL window
// will be sufficient for us too on the legacy (DISCARD) path. For
// FLIP_DISCARD we'd need to use DirectComposition (create a
// IDCompositionDevice/Target/Visual), avoid that for now.
if (m_flags.testFlag(SurfaceHasPreMulAlpha) || m_flags.testFlag(SurfaceHasNonPreMulAlpha)) {
useFlipDiscard = false;
if (window->requestedFormat().alphaBufferSize() <= 0)
qWarning("Swapchain says surface has alpha but the window has no alphaBufferSize set. "
"This may lead to problems.");
}
HRESULT hr; HRESULT hr;
if (useFlipDiscard) { if (useFlipDiscard) {
// We use FLIP_DISCARD which implies a buffer count of 2 (as opposed to the // We use FLIP_DISCARD which implies a buffer count of 2 (as opposed to the
@ -3762,18 +3837,17 @@ bool QD3D11SwapChain::buildOrResize()
DXGI_SWAP_CHAIN_DESC1 desc; DXGI_SWAP_CHAIN_DESC1 desc;
memset(&desc, 0, sizeof(desc)); memset(&desc, 0, sizeof(desc));
desc.Width = pixelSize.width(); desc.Width = UINT(pixelSize.width());
desc.Height = pixelSize.height(); desc.Height = UINT(pixelSize.height());
desc.Format = colorFormat; desc.Format = colorFormat;
desc.SampleDesc.Count = 1; desc.SampleDesc.Count = 1;
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
desc.BufferCount = BUFFER_COUNT; desc.BufferCount = BUFFER_COUNT;
desc.Scaling = DXGI_SCALING_STRETCH; desc.Scaling = DXGI_SCALING_STRETCH;
desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
if (m_flags.testFlag(SurfaceHasPreMulAlpha)) // Do not bother with AlphaMode, if won't work unless we go through
desc.AlphaMode = DXGI_ALPHA_MODE_PREMULTIPLIED; // DirectComposition. Instead, we just take the other (DISCARD)
else if (m_flags.testFlag(SurfaceHasNonPreMulAlpha)) // path for now when alpha is requested.
desc.AlphaMode = DXGI_ALPHA_MODE_STRAIGHT;
desc.Flags = swapChainFlags; desc.Flags = swapChainFlags;
IDXGISwapChain1 *sc1; IDXGISwapChain1 *sc1;
@ -3788,8 +3862,8 @@ bool QD3D11SwapChain::buildOrResize()
DXGI_SWAP_CHAIN_DESC desc; DXGI_SWAP_CHAIN_DESC desc;
memset(&desc, 0, sizeof(desc)); memset(&desc, 0, sizeof(desc));
desc.BufferDesc.Width = pixelSize.width(); desc.BufferDesc.Width = UINT(pixelSize.width());
desc.BufferDesc.Height = pixelSize.height(); desc.BufferDesc.Height = UINT(pixelSize.height());
desc.BufferDesc.RefreshRate.Numerator = 60; desc.BufferDesc.RefreshRate.Numerator = 60;
desc.BufferDesc.RefreshRate.Denominator = 1; desc.BufferDesc.RefreshRate.Denominator = 1;
desc.BufferDesc.Format = colorFormat; desc.BufferDesc.Format = colorFormat;
@ -3811,9 +3885,13 @@ bool QD3D11SwapChain::buildOrResize()
} else { } else {
releaseBuffers(); releaseBuffers();
const UINT count = useFlipDiscard ? BUFFER_COUNT : 1; const UINT count = useFlipDiscard ? BUFFER_COUNT : 1;
HRESULT hr = swapChain->ResizeBuffers(count, pixelSize.width(), pixelSize.height(), HRESULT hr = swapChain->ResizeBuffers(count, UINT(pixelSize.width()), UINT(pixelSize.height()),
colorFormat, swapChainFlags); colorFormat, swapChainFlags);
if (FAILED(hr)) { if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET) {
qWarning("Device loss detected in ResizeBuffers()");
rhiD->deviceLost = true;
return false;
} else if (FAILED(hr)) {
qWarning("Failed to resize D3D11 swapchain: %s", qPrintable(comErrorMessage(hr))); qWarning("Failed to resize D3D11 swapchain: %s", qPrintable(comErrorMessage(hr)));
return false; return false;
} }
@ -3874,13 +3952,13 @@ bool QD3D11SwapChain::buildOrResize()
QD3D11ReferenceRenderTarget *rtD = QRHI_RES(QD3D11ReferenceRenderTarget, &rt); QD3D11ReferenceRenderTarget *rtD = QRHI_RES(QD3D11ReferenceRenderTarget, &rt);
rtD->d.rp = QRHI_RES(QD3D11RenderPassDescriptor, m_renderPassDesc); rtD->d.rp = QRHI_RES(QD3D11RenderPassDescriptor, m_renderPassDesc);
rtD->d.pixelSize = pixelSize; rtD->d.pixelSize = pixelSize;
rtD->d.dpr = window->devicePixelRatio(); rtD->d.dpr = float(window->devicePixelRatio());
rtD->d.sampleCount = sampleDesc.Count; rtD->d.sampleCount = int(sampleDesc.Count);
rtD->d.colorAttCount = 1; rtD->d.colorAttCount = 1;
rtD->d.dsAttCount = m_depthStencil ? 1 : 0; rtD->d.dsAttCount = m_depthStencil ? 1 : 0;
QRHI_PROF; QRHI_PROF;
QRHI_PROF_F(resizeSwapChain(this, BUFFER_COUNT, sampleDesc.Count > 1 ? BUFFER_COUNT : 0, sampleDesc.Count)); QRHI_PROF_F(resizeSwapChain(this, BUFFER_COUNT, sampleDesc.Count > 1 ? BUFFER_COUNT : 0, int(sampleDesc.Count)));
if (rhiP) { if (rhiP) {
D3D11_QUERY_DESC queryDesc; D3D11_QUERY_DESC queryDesc;
memset(&queryDesc, 0, sizeof(queryDesc)); memset(&queryDesc, 0, sizeof(queryDesc));
@ -3914,4 +3992,34 @@ bool QD3D11SwapChain::buildOrResize()
return true; return true;
} }
void QRhiD3D11::DeviceCurse::initResources()
{
framesLeft = framesToActivate;
HRESULT hr = q->dev->CreateComputeShader(g_killDeviceByTimingOut, sizeof(g_killDeviceByTimingOut), nullptr, &cs);
if (FAILED(hr)) {
qWarning("Failed to create compute shader: %s", qPrintable(comErrorMessage(hr)));
return;
}
}
void QRhiD3D11::DeviceCurse::releaseResources()
{
if (cs) {
cs->Release();
cs = nullptr;
}
}
void QRhiD3D11::DeviceCurse::activate()
{
if (!cs)
return;
qDebug("Activating Curse. Goodbye Cruel World.");
q->context->CSSetShader(cs, nullptr, 0);
q->context->Dispatch(256, 1, 1);
}
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -58,6 +58,9 @@ QT_BEGIN_NAMESPACE
struct Q_GUI_EXPORT QRhiD3D11InitParams : public QRhiInitParams struct Q_GUI_EXPORT QRhiD3D11InitParams : public QRhiInitParams
{ {
bool enableDebugLayer = false; bool enableDebugLayer = false;
int framesUntilKillingDeviceViaTdr = -1;
bool repeatDeviceKill = false;
}; };
struct Q_GUI_EXPORT QRhiD3D11NativeHandles : public QRhiNativeHandles struct Q_GUI_EXPORT QRhiD3D11NativeHandles : public QRhiNativeHandles

View File

@ -631,8 +631,9 @@ public:
int resourceLimit(QRhi::ResourceLimit limit) const override; int resourceLimit(QRhi::ResourceLimit limit) const override;
const QRhiNativeHandles *nativeHandles() override; const QRhiNativeHandles *nativeHandles() override;
void sendVMemStatsToProfiler() override; void sendVMemStatsToProfiler() override;
void makeThreadLocalNativeContextCurrent() override; bool makeThreadLocalNativeContextCurrent() override;
void releaseCachedResources() override; void releaseCachedResources() override;
bool isDeviceLost() const override;
void enqueueSubresUpload(QD3D11Texture *texD, QD3D11CommandBuffer *cbD, void enqueueSubresUpload(QD3D11Texture *texD, QD3D11CommandBuffer *cbD,
int layer, int level, const QRhiTextureSubresourceUploadDescription &subresDesc); int layer, int level, const QRhiTextureSubresourceUploadDescription &subresDesc);
@ -658,6 +659,7 @@ public:
IDXGIFactory1 *dxgiFactory = nullptr; IDXGIFactory1 *dxgiFactory = nullptr;
bool hasDxgi2 = false; bool hasDxgi2 = false;
bool supportsFlipDiscardSwapchain = false; bool supportsFlipDiscardSwapchain = false;
bool deviceLost = false;
QRhiD3D11NativeHandles nativeHandlesStruct; QRhiD3D11NativeHandles nativeHandlesStruct;
struct { struct {
@ -694,6 +696,19 @@ public:
QByteArray bytecode; QByteArray bytecode;
}; };
QHash<QRhiShaderStage, Shader> m_shaderCache; QHash<QRhiShaderStage, Shader> m_shaderCache;
struct DeviceCurse {
DeviceCurse(QRhiD3D11 *impl) : q(impl) { }
QRhiD3D11 *q;
int framesToActivate = -1;
bool permanent = false;
int framesLeft = 0;
ID3D11ComputeShader *cs = nullptr;
void initResources();
void releaseResources();
void activate();
} deviceCurse;
}; };
Q_DECLARE_TYPEINFO(QRhiD3D11::ActiveReadback, Q_MOVABLE_TYPE); Q_DECLARE_TYPEINFO(QRhiD3D11::ActiveReadback, Q_MOVABLE_TYPE);

View File

@ -371,7 +371,12 @@ bool QRhiGles2::ensureContext(QSurface *surface) const
return true; return true;
if (!ctx->makeCurrent(surface)) { if (!ctx->makeCurrent(surface)) {
qWarning("QRhiGles2: Failed to make context current. Expect bad things to happen."); if (ctx->isValid()) {
qWarning("QRhiGles2: Failed to make context current. Expect bad things to happen.");
} else {
qWarning("QRhiGles2: Context is lost.");
contextLost = true;
}
return false; return false;
} }
@ -491,6 +496,8 @@ bool QRhiGles2::create(QRhi::Flags flags)
nativeHandlesStruct.context = ctx; nativeHandlesStruct.context = ctx;
contextLost = false;
return true; return true;
} }
@ -654,7 +661,7 @@ static inline GLenum toGlCompressedTextureFormat(QRhiTexture::Format format, QRh
bool QRhiGles2::isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags) const bool QRhiGles2::isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags) const
{ {
if (isCompressedFormat(format)) if (isCompressedFormat(format))
return supportedCompressedFormats.contains(toGlCompressedTextureFormat(format, flags)); return supportedCompressedFormats.contains(GLint(toGlCompressedTextureFormat(format, flags)));
switch (format) { switch (format) {
case QRhiTexture::D16: case QRhiTexture::D16:
@ -753,12 +760,12 @@ void QRhiGles2::sendVMemStatsToProfiler()
// nothing to do here // nothing to do here
} }
void QRhiGles2::makeThreadLocalNativeContextCurrent() bool QRhiGles2::makeThreadLocalNativeContextCurrent()
{ {
if (inFrame && !ofr.active) if (inFrame && !ofr.active)
ensureContext(currentSwapChain->surface); return ensureContext(currentSwapChain->surface);
else else
ensureContext(); return ensureContext();
} }
void QRhiGles2::releaseCachedResources() void QRhiGles2::releaseCachedResources()
@ -772,6 +779,11 @@ void QRhiGles2::releaseCachedResources()
m_shaderCache.clear(); m_shaderCache.clear();
} }
bool QRhiGles2::isDeviceLost() const
{
return contextLost;
}
QRhiRenderBuffer *QRhiGles2::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize, QRhiRenderBuffer *QRhiGles2::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
int sampleCount, QRhiRenderBuffer::Flags flags) int sampleCount, QRhiRenderBuffer::Flags flags)
{ {
@ -930,7 +942,7 @@ void QRhiGles2::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind
uint *p = cmd.args.bindShaderResources.dynamicOffsetPairs; uint *p = cmd.args.bindShaderResources.dynamicOffsetPairs;
for (int i = 0; i < dynamicOffsetCount; ++i) { for (int i = 0; i < dynamicOffsetCount; ++i) {
const QRhiCommandBuffer::DynamicOffset &dynOfs(dynamicOffsets[i]); const QRhiCommandBuffer::DynamicOffset &dynOfs(dynamicOffsets[i]);
*p++ = dynOfs.first; *p++ = uint(dynOfs.first);
*p++ = dynOfs.second; *p++ = dynOfs.second;
} }
} else { } else {
@ -1023,10 +1035,10 @@ void QRhiGles2::setBlendConstants(QRhiCommandBuffer *cb, const QColor &c)
QGles2CommandBuffer::Command cmd; QGles2CommandBuffer::Command cmd;
cmd.cmd = QGles2CommandBuffer::Command::BlendConstants; cmd.cmd = QGles2CommandBuffer::Command::BlendConstants;
cmd.args.blendConstants.r = c.redF(); cmd.args.blendConstants.r = float(c.redF());
cmd.args.blendConstants.g = c.greenF(); cmd.args.blendConstants.g = float(c.greenF());
cmd.args.blendConstants.b = c.blueF(); cmd.args.blendConstants.b = float(c.blueF());
cmd.args.blendConstants.a = c.alphaF(); cmd.args.blendConstants.a = float(c.alphaF());
cbD->commands.append(cmd); cbD->commands.append(cmd);
} }
@ -1156,7 +1168,7 @@ QRhi::FrameOpResult QRhiGles2::beginFrame(QRhiSwapChain *swapChain, QRhi::BeginF
QGles2SwapChain *swapChainD = QRHI_RES(QGles2SwapChain, swapChain); QGles2SwapChain *swapChainD = QRHI_RES(QGles2SwapChain, swapChain);
if (!ensureContext(swapChainD->surface)) if (!ensureContext(swapChainD->surface))
return QRhi::FrameOpError; return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
currentSwapChain = swapChainD; currentSwapChain = swapChainD;
@ -1179,7 +1191,7 @@ QRhi::FrameOpResult QRhiGles2::endFrame(QRhiSwapChain *swapChain, QRhi::EndFrame
addBoundaryCommand(&swapChainD->cb, QGles2CommandBuffer::Command::EndFrame); addBoundaryCommand(&swapChainD->cb, QGles2CommandBuffer::Command::EndFrame);
if (!ensureContext(swapChainD->surface)) if (!ensureContext(swapChainD->surface))
return QRhi::FrameOpError; return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
executeCommandBuffer(&swapChainD->cb); executeCommandBuffer(&swapChainD->cb);
@ -1203,7 +1215,7 @@ QRhi::FrameOpResult QRhiGles2::beginOffscreenFrame(QRhiCommandBuffer **cb, QRhi:
{ {
Q_UNUSED(flags); Q_UNUSED(flags);
if (!ensureContext()) if (!ensureContext())
return QRhi::FrameOpError; return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
ofr.active = true; ofr.active = true;
@ -1225,7 +1237,7 @@ QRhi::FrameOpResult QRhiGles2::endOffscreenFrame(QRhi::EndFrameFlags flags)
addBoundaryCommand(&ofr.cbWrapper, QGles2CommandBuffer::Command::EndFrame); addBoundaryCommand(&ofr.cbWrapper, QGles2CommandBuffer::Command::EndFrame);
if (!ensureContext()) if (!ensureContext())
return QRhi::FrameOpError; return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
executeCommandBuffer(&ofr.cbWrapper); executeCommandBuffer(&ofr.cbWrapper);
@ -1239,14 +1251,14 @@ QRhi::FrameOpResult QRhiGles2::finish()
Q_ASSERT(!currentSwapChain); Q_ASSERT(!currentSwapChain);
Q_ASSERT(ofr.cbWrapper.recordingPass == QGles2CommandBuffer::NoPass); Q_ASSERT(ofr.cbWrapper.recordingPass == QGles2CommandBuffer::NoPass);
if (!ensureContext()) if (!ensureContext())
return QRhi::FrameOpError; return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
executeCommandBuffer(&ofr.cbWrapper); executeCommandBuffer(&ofr.cbWrapper);
ofr.cbWrapper.resetCommands(); ofr.cbWrapper.resetCommands();
} else { } else {
Q_ASSERT(currentSwapChain); Q_ASSERT(currentSwapChain);
Q_ASSERT(currentSwapChain->cb.recordingPass == QGles2CommandBuffer::NoPass); Q_ASSERT(currentSwapChain->cb.recordingPass == QGles2CommandBuffer::NoPass);
if (!ensureContext(currentSwapChain->surface)) if (!ensureContext(currentSwapChain->surface))
return QRhi::FrameOpError; return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
executeCommandBuffer(&currentSwapChain->cb); executeCommandBuffer(&currentSwapChain->cb);
currentSwapChain->cb.resetCommands(); currentSwapChain->cb.resetCommands();
} }
@ -1314,7 +1326,7 @@ void QRhiGles2::enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cb
} }
cmd.args.subImage.target = texD->target; cmd.args.subImage.target = texD->target;
cmd.args.subImage.texture = texD->texture; cmd.args.subImage.texture = texD->texture;
cmd.args.subImage.faceTarget = faceTargetBase + layer; cmd.args.subImage.faceTarget = faceTargetBase + uint(layer);
cmd.args.subImage.level = level; cmd.args.subImage.level = level;
cmd.args.subImage.dx = dp.x(); cmd.args.subImage.dx = dp.x();
cmd.args.subImage.dy = dp.y(); cmd.args.subImage.dy = dp.y();
@ -1333,7 +1345,7 @@ void QRhiGles2::enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cb
cmd.cmd = QGles2CommandBuffer::Command::CompressedSubImage; cmd.cmd = QGles2CommandBuffer::Command::CompressedSubImage;
cmd.args.compressedSubImage.target = texD->target; cmd.args.compressedSubImage.target = texD->target;
cmd.args.compressedSubImage.texture = texD->texture; cmd.args.compressedSubImage.texture = texD->texture;
cmd.args.compressedSubImage.faceTarget = faceTargetBase + layer; cmd.args.compressedSubImage.faceTarget = faceTargetBase + uint(layer);
cmd.args.compressedSubImage.level = level; cmd.args.compressedSubImage.level = level;
cmd.args.compressedSubImage.dx = dp.x(); cmd.args.compressedSubImage.dx = dp.x();
cmd.args.compressedSubImage.dy = dp.y(); cmd.args.compressedSubImage.dy = dp.y();
@ -1348,7 +1360,7 @@ void QRhiGles2::enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cb
cmd.cmd = QGles2CommandBuffer::Command::CompressedImage; cmd.cmd = QGles2CommandBuffer::Command::CompressedImage;
cmd.args.compressedImage.target = texD->target; cmd.args.compressedImage.target = texD->target;
cmd.args.compressedImage.texture = texD->texture; cmd.args.compressedImage.texture = texD->texture;
cmd.args.compressedImage.faceTarget = faceTargetBase + layer; cmd.args.compressedImage.faceTarget = faceTargetBase + uint(layer);
cmd.args.compressedImage.level = level; cmd.args.compressedImage.level = level;
cmd.args.compressedImage.glintformat = texD->glintformat; cmd.args.compressedImage.glintformat = texD->glintformat;
cmd.args.compressedImage.w = size.width(); cmd.args.compressedImage.w = size.width();
@ -1366,7 +1378,7 @@ void QRhiGles2::enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cb
cmd.cmd = QGles2CommandBuffer::Command::SubImage; cmd.cmd = QGles2CommandBuffer::Command::SubImage;
cmd.args.subImage.target = texD->target; cmd.args.subImage.target = texD->target;
cmd.args.subImage.texture = texD->texture; cmd.args.subImage.texture = texD->texture;
cmd.args.subImage.faceTarget = faceTargetBase + layer; cmd.args.subImage.faceTarget = faceTargetBase + uint(layer);
cmd.args.subImage.level = level; cmd.args.subImage.level = level;
cmd.args.subImage.dx = dp.x(); cmd.args.subImage.dx = dp.x();
cmd.args.subImage.dy = dp.y(); cmd.args.subImage.dy = dp.y();
@ -1394,7 +1406,7 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, u.buf); QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, u.buf);
Q_ASSERT(bufD->m_type == QRhiBuffer::Dynamic); Q_ASSERT(bufD->m_type == QRhiBuffer::Dynamic);
if (bufD->m_usage.testFlag(QRhiBuffer::UniformBuffer)) { if (bufD->m_usage.testFlag(QRhiBuffer::UniformBuffer)) {
memcpy(bufD->ubuf.data() + u.offset, u.data.constData(), u.data.size()); memcpy(bufD->ubuf.data() + u.offset, u.data.constData(), size_t(u.data.size()));
} else { } else {
trackedBufferBarrier(cbD, bufD, QGles2Buffer::AccessUpdate); trackedBufferBarrier(cbD, bufD, QGles2Buffer::AccessUpdate);
QGles2CommandBuffer::Command cmd; QGles2CommandBuffer::Command cmd;
@ -1413,7 +1425,7 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
Q_ASSERT(bufD->m_type != QRhiBuffer::Dynamic); Q_ASSERT(bufD->m_type != QRhiBuffer::Dynamic);
Q_ASSERT(u.offset + u.data.size() <= bufD->m_size); Q_ASSERT(u.offset + u.data.size() <= bufD->m_size);
if (bufD->m_usage.testFlag(QRhiBuffer::UniformBuffer)) { if (bufD->m_usage.testFlag(QRhiBuffer::UniformBuffer)) {
memcpy(bufD->ubuf.data() + u.offset, u.data.constData(), u.data.size()); memcpy(bufD->ubuf.data() + u.offset, u.data.constData(), size_t(u.data.size()));
} else { } else {
trackedBufferBarrier(cbD, bufD, QGles2Buffer::AccessUpdate); trackedBufferBarrier(cbD, bufD, QGles2Buffer::AccessUpdate);
QGles2CommandBuffer::Command cmd; QGles2CommandBuffer::Command cmd;
@ -1458,7 +1470,7 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
QGles2CommandBuffer::Command cmd; QGles2CommandBuffer::Command cmd;
cmd.cmd = QGles2CommandBuffer::Command::CopyTex; cmd.cmd = QGles2CommandBuffer::Command::CopyTex;
cmd.args.copyTex.srcFaceTarget = srcFaceTargetBase + u.copy.desc.sourceLayer(); cmd.args.copyTex.srcFaceTarget = srcFaceTargetBase + uint(u.copy.desc.sourceLayer());
cmd.args.copyTex.srcTexture = srcD->texture; cmd.args.copyTex.srcTexture = srcD->texture;
cmd.args.copyTex.srcLevel = u.copy.desc.sourceLevel(); cmd.args.copyTex.srcLevel = u.copy.desc.sourceLevel();
cmd.args.copyTex.srcX = sp.x(); cmd.args.copyTex.srcX = sp.x();
@ -1466,7 +1478,7 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
cmd.args.copyTex.dstTarget = dstD->target; cmd.args.copyTex.dstTarget = dstD->target;
cmd.args.copyTex.dstTexture = dstD->texture; cmd.args.copyTex.dstTexture = dstD->texture;
cmd.args.copyTex.dstFaceTarget = dstFaceTargetBase + u.copy.desc.destinationLayer(); cmd.args.copyTex.dstFaceTarget = dstFaceTargetBase + uint(u.copy.desc.destinationLayer());
cmd.args.copyTex.dstLevel = u.copy.desc.destinationLevel(); cmd.args.copyTex.dstLevel = u.copy.desc.destinationLevel();
cmd.args.copyTex.dstX = dp.x(); cmd.args.copyTex.dstX = dp.x();
cmd.args.copyTex.dstY = dp.y(); cmd.args.copyTex.dstY = dp.y();
@ -1480,7 +1492,8 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
cmd.cmd = QGles2CommandBuffer::Command::ReadPixels; cmd.cmd = QGles2CommandBuffer::Command::ReadPixels;
cmd.args.readPixels.result = u.read.result; cmd.args.readPixels.result = u.read.result;
QGles2Texture *texD = QRHI_RES(QGles2Texture, u.read.rb.texture()); QGles2Texture *texD = QRHI_RES(QGles2Texture, u.read.rb.texture());
trackedImageBarrier(cbD, texD, QGles2Texture::AccessRead); if (texD)
trackedImageBarrier(cbD, texD, QGles2Texture::AccessRead);
cmd.args.readPixels.texture = texD ? texD->texture : 0; cmd.args.readPixels.texture = texD ? texD->texture : 0;
if (texD) { if (texD) {
cmd.args.readPixels.w = texD->m_pixelSize.width(); cmd.args.readPixels.w = texD->m_pixelSize.width();
@ -1488,7 +1501,7 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
cmd.args.readPixels.format = texD->m_format; cmd.args.readPixels.format = texD->m_format;
const GLenum faceTargetBase = texD->m_flags.testFlag(QRhiTexture::CubeMap) const GLenum faceTargetBase = texD->m_flags.testFlag(QRhiTexture::CubeMap)
? GL_TEXTURE_CUBE_MAP_POSITIVE_X : texD->target; ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : texD->target;
cmd.args.readPixels.readTarget = faceTargetBase + u.read.rb.layer(); cmd.args.readPixels.readTarget = faceTargetBase + uint(u.read.rb.layer());
cmd.args.readPixels.level = u.read.rb.level(); cmd.args.readPixels.level = u.read.rb.level();
} }
cbD->commands.append(cmd); cbD->commands.append(cmd);
@ -1848,7 +1861,7 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
f->glBindVertexArray(0); f->glBindVertexArray(0);
break; break;
case QGles2CommandBuffer::Command::Viewport: case QGles2CommandBuffer::Command::Viewport:
f->glViewport(cmd.args.viewport.x, cmd.args.viewport.y, cmd.args.viewport.w, cmd.args.viewport.h); f->glViewport(GLint(cmd.args.viewport.x), GLint(cmd.args.viewport.y), GLsizei(cmd.args.viewport.w), GLsizei(cmd.args.viewport.h));
f->glDepthRangef(cmd.args.viewport.d0, cmd.args.viewport.d1); f->glDepthRangef(cmd.args.viewport.d0, cmd.args.viewport.d1);
break; break;
case QGles2CommandBuffer::Command::Scissor: case QGles2CommandBuffer::Command::Scissor:
@ -1861,8 +1874,8 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
{ {
QGles2GraphicsPipeline *psD = QRHI_RES(QGles2GraphicsPipeline, cmd.args.stencilRef.ps); QGles2GraphicsPipeline *psD = QRHI_RES(QGles2GraphicsPipeline, cmd.args.stencilRef.ps);
if (psD) { if (psD) {
f->glStencilFuncSeparate(GL_FRONT, toGlCompareOp(psD->m_stencilFront.compareOp), cmd.args.stencilRef.ref, psD->m_stencilReadMask); f->glStencilFuncSeparate(GL_FRONT, toGlCompareOp(psD->m_stencilFront.compareOp), GLint(cmd.args.stencilRef.ref), psD->m_stencilReadMask);
f->glStencilFuncSeparate(GL_BACK, toGlCompareOp(psD->m_stencilBack.compareOp), cmd.args.stencilRef.ref, psD->m_stencilReadMask); f->glStencilFuncSeparate(GL_BACK, toGlCompareOp(psD->m_stencilBack.compareOp), GLint(cmd.args.stencilRef.ref), psD->m_stencilReadMask);
} else { } else {
qWarning("No graphics pipeline active for setStencilRef; ignored"); qWarning("No graphics pipeline active for setStencilRef; ignored");
} }
@ -1882,7 +1895,7 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
// we do not support more than one vertex buffer // we do not support more than one vertex buffer
f->glBindBuffer(GL_ARRAY_BUFFER, cmd.args.bindVertexBuffer.buffer); f->glBindBuffer(GL_ARRAY_BUFFER, cmd.args.bindVertexBuffer.buffer);
const int stride = bindings[bindingIdx].stride(); const int stride = int(bindings[bindingIdx].stride());
int size = 1; int size = 1;
GLenum type = GL_FLOAT; GLenum type = GL_FLOAT;
bool normalize = false; bool normalize = false;
@ -1924,13 +1937,13 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
const int locationIdx = a.location(); const int locationIdx = a.location();
quint32 ofs = a.offset() + cmd.args.bindVertexBuffer.offset; quint32 ofs = a.offset() + cmd.args.bindVertexBuffer.offset;
f->glVertexAttribPointer(locationIdx, size, type, normalize, stride, f->glVertexAttribPointer(GLuint(locationIdx), size, type, normalize, stride,
reinterpret_cast<const GLvoid *>(quintptr(ofs))); reinterpret_cast<const GLvoid *>(quintptr(ofs)));
f->glEnableVertexAttribArray(locationIdx); f->glEnableVertexAttribArray(GLuint(locationIdx));
if (bindings[bindingIdx].classification() == QRhiVertexInputBinding::PerInstance if (bindings[bindingIdx].classification() == QRhiVertexInputBinding::PerInstance
&& caps.instancing) && caps.instancing)
{ {
f->glVertexAttribDivisor(locationIdx, bindings[bindingIdx].instanceStepRate()); f->glVertexAttribDivisor(GLuint(locationIdx), GLuint(bindings[bindingIdx].instanceStepRate()));
} }
} }
} else { } else {
@ -1949,10 +1962,10 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
QGles2GraphicsPipeline *psD = QRHI_RES(QGles2GraphicsPipeline, cmd.args.draw.ps); QGles2GraphicsPipeline *psD = QRHI_RES(QGles2GraphicsPipeline, cmd.args.draw.ps);
if (psD) { if (psD) {
if (cmd.args.draw.instanceCount == 1 || !caps.instancing) { if (cmd.args.draw.instanceCount == 1 || !caps.instancing) {
f->glDrawArrays(psD->drawMode, cmd.args.draw.firstVertex, cmd.args.draw.vertexCount); f->glDrawArrays(psD->drawMode, GLint(cmd.args.draw.firstVertex), GLsizei(cmd.args.draw.vertexCount));
} else { } else {
f->glDrawArraysInstanced(psD->drawMode, cmd.args.draw.firstVertex, cmd.args.draw.vertexCount, f->glDrawArraysInstanced(psD->drawMode, GLint(cmd.args.draw.firstVertex), GLsizei(cmd.args.draw.vertexCount),
cmd.args.draw.instanceCount); GLsizei(cmd.args.draw.instanceCount));
} }
} else { } else {
qWarning("No graphics pipeline active for draw; ignored"); qWarning("No graphics pipeline active for draw; ignored");
@ -1968,30 +1981,30 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
if (cmd.args.drawIndexed.instanceCount == 1 || !caps.instancing) { if (cmd.args.drawIndexed.instanceCount == 1 || !caps.instancing) {
if (cmd.args.drawIndexed.baseVertex != 0 && caps.baseVertex) { if (cmd.args.drawIndexed.baseVertex != 0 && caps.baseVertex) {
f->glDrawElementsBaseVertex(psD->drawMode, f->glDrawElementsBaseVertex(psD->drawMode,
cmd.args.drawIndexed.indexCount, GLsizei(cmd.args.drawIndexed.indexCount),
indexType, indexType,
ofs, ofs,
cmd.args.drawIndexed.baseVertex); cmd.args.drawIndexed.baseVertex);
} else { } else {
f->glDrawElements(psD->drawMode, f->glDrawElements(psD->drawMode,
cmd.args.drawIndexed.indexCount, GLsizei(cmd.args.drawIndexed.indexCount),
indexType, indexType,
ofs); ofs);
} }
} else { } else {
if (cmd.args.drawIndexed.baseVertex != 0 && caps.baseVertex) { if (cmd.args.drawIndexed.baseVertex != 0 && caps.baseVertex) {
f->glDrawElementsInstancedBaseVertex(psD->drawMode, f->glDrawElementsInstancedBaseVertex(psD->drawMode,
cmd.args.drawIndexed.indexCount, GLsizei(cmd.args.drawIndexed.indexCount),
indexType, indexType,
ofs, ofs,
cmd.args.drawIndexed.instanceCount, GLsizei(cmd.args.drawIndexed.instanceCount),
cmd.args.drawIndexed.baseVertex); cmd.args.drawIndexed.baseVertex);
} else { } else {
f->glDrawElementsInstanced(psD->drawMode, f->glDrawElementsInstanced(psD->drawMode,
cmd.args.drawIndexed.indexCount, GLsizei(cmd.args.drawIndexed.indexCount),
indexType, indexType,
ofs, ofs,
cmd.args.drawIndexed.instanceCount); GLsizei(cmd.args.drawIndexed.instanceCount));
} }
} }
} else { } else {
@ -2016,7 +2029,7 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
const int colorAttCount = cmd.args.bindFramebuffer.colorAttCount; const int colorAttCount = cmd.args.bindFramebuffer.colorAttCount;
QVarLengthArray<GLenum, 8> bufs; QVarLengthArray<GLenum, 8> bufs;
for (int i = 0; i < colorAttCount; ++i) for (int i = 0; i < colorAttCount; ++i)
bufs.append(GL_COLOR_ATTACHMENT0 + i); bufs.append(GL_COLOR_ATTACHMENT0 + uint(i));
f->glDrawBuffers(colorAttCount, bufs.constData()); f->glDrawBuffers(colorAttCount, bufs.constData());
} }
} else { } else {
@ -2044,7 +2057,7 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
f->glClearDepthf(cmd.args.clear.d); f->glClearDepthf(cmd.args.clear.d);
} }
if (cmd.args.clear.mask & GL_STENCIL_BUFFER_BIT) if (cmd.args.clear.mask & GL_STENCIL_BUFFER_BIT)
f->glClearStencil(cmd.args.clear.s); f->glClearStencil(GLint(cmd.args.clear.s));
f->glClear(cmd.args.clear.mask); f->glClear(cmd.args.clear.mask);
break; break;
case QGles2CommandBuffer::Command::BufferSubData: case QGles2CommandBuffer::Command::BufferSubData:
@ -2288,7 +2301,7 @@ void QRhiGles2::bindShaderResources(QRhiGraphicsPipeline *maybeGraphicsPs, QRhiC
if (dynOfsCount) { if (dynOfsCount) {
for (int j = 0; j < dynOfsCount; ++j) { for (int j = 0; j < dynOfsCount; ++j) {
if (dynOfsPairs[2 * j] == uint(b->binding)) { if (dynOfsPairs[2 * j] == uint(b->binding)) {
viewOffset = dynOfsPairs[2 * j + 1]; viewOffset = int(dynOfsPairs[2 * j + 1]);
break; break;
} }
} }
@ -2379,20 +2392,20 @@ void QRhiGles2::bindShaderResources(QRhiGraphicsPipeline *maybeGraphicsPs, QRhiC
for (QGles2SamplerDescription &sampler : samplers) { for (QGles2SamplerDescription &sampler : samplers) {
if (sampler.binding == b->binding) { if (sampler.binding == b->binding) {
f->glActiveTexture(GL_TEXTURE0 + texUnit); f->glActiveTexture(GL_TEXTURE0 + uint(texUnit));
f->glBindTexture(texD->target, texD->texture); f->glBindTexture(texD->target, texD->texture);
if (texD->samplerState != samplerD->d) { if (texD->samplerState != samplerD->d) {
f->glTexParameteri(texD->target, GL_TEXTURE_MIN_FILTER, samplerD->d.glminfilter); f->glTexParameteri(texD->target, GL_TEXTURE_MIN_FILTER, GLint(samplerD->d.glminfilter));
f->glTexParameteri(texD->target, GL_TEXTURE_MAG_FILTER, samplerD->d.glmagfilter); f->glTexParameteri(texD->target, GL_TEXTURE_MAG_FILTER, GLint(samplerD->d.glmagfilter));
f->glTexParameteri(texD->target, GL_TEXTURE_WRAP_S, samplerD->d.glwraps); f->glTexParameteri(texD->target, GL_TEXTURE_WRAP_S, GLint(samplerD->d.glwraps));
f->glTexParameteri(texD->target, GL_TEXTURE_WRAP_T, samplerD->d.glwrapt); f->glTexParameteri(texD->target, GL_TEXTURE_WRAP_T, GLint(samplerD->d.glwrapt));
// 3D textures not supported by GLES 2.0 or by us atm... // 3D textures not supported by GLES 2.0 or by us atm...
//f->glTexParameteri(texD->target, GL_TEXTURE_WRAP_R, samplerD->d.glwrapr); //f->glTexParameteri(texD->target, GL_TEXTURE_WRAP_R, samplerD->d.glwrapr);
if (caps.textureCompareMode) { if (caps.textureCompareMode) {
if (samplerD->d.gltexcomparefunc != GL_NEVER) { if (samplerD->d.gltexcomparefunc != GL_NEVER) {
f->glTexParameteri(texD->target, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); f->glTexParameteri(texD->target, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
f->glTexParameteri(texD->target, GL_TEXTURE_COMPARE_FUNC, samplerD->d.gltexcomparefunc); f->glTexParameteri(texD->target, GL_TEXTURE_COMPARE_FUNC, GLint(samplerD->d.gltexcomparefunc));
} else { } else {
f->glTexParameteri(texD->target, GL_TEXTURE_COMPARE_MODE, GL_NONE); f->glTexParameteri(texD->target, GL_TEXTURE_COMPARE_MODE, GL_NONE);
} }
@ -2419,7 +2432,7 @@ void QRhiGles2::bindShaderResources(QRhiGraphicsPipeline *maybeGraphicsPs, QRhiC
access = GL_READ_ONLY; access = GL_READ_ONLY;
else if (b->type == QRhiShaderResourceBinding::ImageStore) else if (b->type == QRhiShaderResourceBinding::ImageStore)
access = GL_WRITE_ONLY; access = GL_WRITE_ONLY;
f->glBindImageTexture(b->binding, texD->texture, f->glBindImageTexture(GLuint(b->binding), texD->texture,
b->u.simage.level, layered, 0, b->u.simage.level, layered, 0,
access, texD->glsizedintformat); access, texD->glsizedintformat);
} }
@ -2432,9 +2445,9 @@ void QRhiGles2::bindShaderResources(QRhiGraphicsPipeline *maybeGraphicsPs, QRhiC
{ {
QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, b->u.sbuf.buf); QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, b->u.sbuf.buf);
if (b->u.sbuf.offset == 0 && b->u.sbuf.maybeSize == 0) if (b->u.sbuf.offset == 0 && b->u.sbuf.maybeSize == 0)
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, b->binding, bufD->buffer); f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, GLuint(b->binding), bufD->buffer);
else else
f->glBindBufferRange(GL_SHADER_STORAGE_BUFFER, b->binding, bufD->buffer, f->glBindBufferRange(GL_SHADER_STORAGE_BUFFER, GLuint(b->binding), bufD->buffer,
b->u.sbuf.offset, b->u.sbuf.maybeSize ? b->u.sbuf.maybeSize : bufD->m_size); b->u.sbuf.offset, b->u.sbuf.maybeSize ? b->u.sbuf.maybeSize : bufD->m_size);
} }
break; break;
@ -2556,10 +2569,10 @@ void QRhiGles2::beginPass(QRhiCommandBuffer *cb,
clearCmd.args.clear.mask |= GL_COLOR_BUFFER_BIT; clearCmd.args.clear.mask |= GL_COLOR_BUFFER_BIT;
if (rtD->dsAttCount && wantsDsClear) if (rtD->dsAttCount && wantsDsClear)
clearCmd.args.clear.mask |= GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT; clearCmd.args.clear.mask |= GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
clearCmd.args.clear.c[0] = colorClearValue.redF(); clearCmd.args.clear.c[0] = float(colorClearValue.redF());
clearCmd.args.clear.c[1] = colorClearValue.greenF(); clearCmd.args.clear.c[1] = float(colorClearValue.greenF());
clearCmd.args.clear.c[2] = colorClearValue.blueF(); clearCmd.args.clear.c[2] = float(colorClearValue.blueF());
clearCmd.args.clear.c[3] = colorClearValue.alphaF(); clearCmd.args.clear.c[3] = float(colorClearValue.alphaF());
clearCmd.args.clear.d = depthStencilClearValue.depthClearValue(); clearCmd.args.clear.d = depthStencilClearValue.depthClearValue();
clearCmd.args.clear.s = depthStencilClearValue.stencilClearValue(); clearCmd.args.clear.s = depthStencilClearValue.stencilClearValue();
cbD->commands.append(clearCmd); cbD->commands.append(clearCmd);
@ -2597,7 +2610,7 @@ void QRhiGles2::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resource
QGles2Texture *colorTexD = QRHI_RES(QGles2Texture, colorAtt.resolveTexture()); QGles2Texture *colorTexD = QRHI_RES(QGles2Texture, colorAtt.resolveTexture());
const GLenum faceTargetBase = colorTexD->m_flags.testFlag(QRhiTexture::CubeMap) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X const GLenum faceTargetBase = colorTexD->m_flags.testFlag(QRhiTexture::CubeMap) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X
: colorTexD->target; : colorTexD->target;
cmd.args.blitFromRb.target = faceTargetBase + colorAtt.resolveLayer(); cmd.args.blitFromRb.target = faceTargetBase + uint(colorAtt.resolveLayer());
cmd.args.blitFromRb.texture = colorTexD->texture; cmd.args.blitFromRb.texture = colorTexD->texture;
cmd.args.blitFromRb.dstLevel = colorAtt.resolveLevel(); cmd.args.blitFromRb.dstLevel = colorAtt.resolveLevel();
cbD->commands.append(cmd); cbD->commands.append(cmd);
@ -2664,9 +2677,9 @@ void QRhiGles2::dispatch(QRhiCommandBuffer *cb, int x, int y, int z)
QGles2CommandBuffer::Command cmd; QGles2CommandBuffer::Command cmd;
cmd.cmd = QGles2CommandBuffer::Command::Dispatch; cmd.cmd = QGles2CommandBuffer::Command::Dispatch;
cmd.args.dispatch.x = x; cmd.args.dispatch.x = GLuint(x);
cmd.args.dispatch.y = y; cmd.args.dispatch.y = GLuint(y);
cmd.args.dispatch.z = z; cmd.args.dispatch.z = GLuint(z);
cbD->commands.append(cmd); cbD->commands.append(cmd);
} }
@ -2818,7 +2831,7 @@ void QRhiGles2::gatherUniforms(GLuint program, const QShaderDescription::Uniform
uniform.glslLocation = f->glGetUniformLocation(program, name.constData()); uniform.glslLocation = f->glGetUniformLocation(program, name.constData());
if (uniform.glslLocation >= 0) { if (uniform.glslLocation >= 0) {
uniform.binding = ub.binding; uniform.binding = ub.binding;
uniform.offset = blockMember.offset; uniform.offset = uint(blockMember.offset);
uniform.size = blockMember.size; uniform.size = blockMember.size;
dst->append(uniform); dst->append(uniform);
} }
@ -2882,7 +2895,7 @@ bool QGles2Buffer::build()
return false; return false;
} }
ubuf.resize(nonZeroSize); ubuf.resize(nonZeroSize);
QRHI_PROF_F(newBuffer(this, nonZeroSize, 0, 1)); QRHI_PROF_F(newBuffer(this, uint(nonZeroSize), 0, 1));
return true; return true;
} }
@ -2901,7 +2914,7 @@ bool QGles2Buffer::build()
usageState.access = AccessNone; usageState.access = AccessNone;
QRHI_PROF_F(newBuffer(this, nonZeroSize, 1, 0)); QRHI_PROF_F(newBuffer(this, uint(nonZeroSize), 1, 0));
rhiD->registerResource(this); rhiD->registerResource(this);
return true; return true;
} }
@ -3172,13 +3185,13 @@ bool QGles2Texture::build()
for (int layer = 0, layerCount = isCube ? 6 : 1; layer != layerCount; ++layer) { for (int layer = 0, layerCount = isCube ? 6 : 1; layer != layerCount; ++layer) {
for (int level = 0; level != mipLevelCount; ++level) { for (int level = 0; level != mipLevelCount; ++level) {
const QSize mipSize = rhiD->q->sizeForMipLevel(level, size); const QSize mipSize = rhiD->q->sizeForMipLevel(level, size);
rhiD->f->glTexImage2D(faceTargetBase + layer, level, glintformat, rhiD->f->glTexImage2D(faceTargetBase + uint(layer), level, GLint(glintformat),
mipSize.width(), mipSize.height(), 0, mipSize.width(), mipSize.height(), 0,
glformat, gltype, nullptr); glformat, gltype, nullptr);
} }
} }
} else { } else {
rhiD->f->glTexImage2D(target, 0, glintformat, size.width(), size.height(), rhiD->f->glTexImage2D(target, 0, GLint(glintformat), size.width(), size.height(),
0, glformat, gltype, nullptr); 0, glformat, gltype, nullptr);
} }
} else { } else {
@ -3381,14 +3394,15 @@ bool QGles2TextureRenderTarget::build()
QGles2Texture *texD = QRHI_RES(QGles2Texture, texture); QGles2Texture *texD = QRHI_RES(QGles2Texture, texture);
Q_ASSERT(texD->texture && texD->specified); Q_ASSERT(texD->texture && texD->specified);
const GLenum faceTargetBase = texD->flags().testFlag(QRhiTexture::CubeMap) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : texD->target; const GLenum faceTargetBase = texD->flags().testFlag(QRhiTexture::CubeMap) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : texD->target;
rhiD->f->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, faceTargetBase + colorAtt.layer(), texD->texture, colorAtt.level()); rhiD->f->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + uint(i), faceTargetBase + uint(colorAtt.layer()),
texD->texture, colorAtt.level());
if (i == 0) { if (i == 0) {
d.pixelSize = texD->pixelSize(); d.pixelSize = texD->pixelSize();
d.sampleCount = 1; d.sampleCount = 1;
} }
} else if (renderBuffer) { } else if (renderBuffer) {
QGles2RenderBuffer *rbD = QRHI_RES(QGles2RenderBuffer, renderBuffer); QGles2RenderBuffer *rbD = QRHI_RES(QGles2RenderBuffer, renderBuffer);
rhiD->f->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_RENDERBUFFER, rbD->renderbuffer); rhiD->f->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + uint(i), GL_RENDERBUFFER, rbD->renderbuffer);
if (i == 0) { if (i == 0) {
d.pixelSize = rbD->pixelSize(); d.pixelSize = rbD->pixelSize();
d.sampleCount = rbD->samples; d.sampleCount = rbD->samples;
@ -3538,7 +3552,7 @@ bool QGles2GraphicsPipeline::build()
for (auto inVar : vsDesc.inputVariables()) { for (auto inVar : vsDesc.inputVariables()) {
const QByteArray name = inVar.name.toUtf8(); const QByteArray name = inVar.name.toUtf8();
rhiD->f->glBindAttribLocation(program, inVar.location, name.constData()); rhiD->f->glBindAttribLocation(program, GLuint(inVar.location), name.constData());
} }
if (!rhiD->linkProgram(program)) if (!rhiD->linkProgram(program))
@ -3684,7 +3698,7 @@ bool QGles2SwapChain::buildOrResize()
rt.d.rp = QRHI_RES(QGles2RenderPassDescriptor, m_renderPassDesc); rt.d.rp = QRHI_RES(QGles2RenderPassDescriptor, m_renderPassDesc);
rt.d.pixelSize = pixelSize; rt.d.pixelSize = pixelSize;
rt.d.dpr = m_window->devicePixelRatio(); rt.d.dpr = float(m_window->devicePixelRatio());
rt.d.sampleCount = qBound(1, m_sampleCount, 64); rt.d.sampleCount = qBound(1, m_sampleCount, 64);
rt.d.colorAttCount = 1; rt.d.colorAttCount = 1;
rt.d.dsAttCount = m_depthStencil ? 1 : 0; rt.d.dsAttCount = m_depthStencil ? 1 : 0;

View File

@ -664,8 +664,9 @@ public:
int resourceLimit(QRhi::ResourceLimit limit) const override; int resourceLimit(QRhi::ResourceLimit limit) const override;
const QRhiNativeHandles *nativeHandles() override; const QRhiNativeHandles *nativeHandles() override;
void sendVMemStatsToProfiler() override; void sendVMemStatsToProfiler() override;
void makeThreadLocalNativeContextCurrent() override; bool makeThreadLocalNativeContextCurrent() override;
void releaseCachedResources() override; void releaseCachedResources() override;
bool isDeviceLost() const override;
bool ensureContext(QSurface *surface = nullptr) const; bool ensureContext(QSurface *surface = nullptr) const;
void executeDeferredReleases(); void executeDeferredReleases();
@ -769,6 +770,7 @@ public:
QVector<GLint> supportedCompressedFormats; QVector<GLint> supportedCompressedFormats;
mutable QVector<int> supportedSampleCountList; mutable QVector<int> supportedSampleCountList;
QRhiGles2NativeHandles nativeHandlesStruct; QRhiGles2NativeHandles nativeHandlesStruct;
mutable bool contextLost = false;
struct DeferredReleaseEntry { struct DeferredReleaseEntry {
enum Type { enum Type {

View File

@ -352,7 +352,8 @@ QRhiMetal::~QRhiMetal()
delete d; delete d;
} }
static inline uint aligned(uint v, uint byteAlign) template <class Int>
inline Int aligned(Int v, Int byteAlign)
{ {
return (v + byteAlign - 1) & ~(byteAlign - 1); return (v + byteAlign - 1) & ~(byteAlign - 1);
} }
@ -582,9 +583,10 @@ void QRhiMetal::sendVMemStatsToProfiler()
// nothing to do here // nothing to do here
} }
void QRhiMetal::makeThreadLocalNativeContextCurrent() bool QRhiMetal::makeThreadLocalNativeContextCurrent()
{ {
// nothing to do here // not applicable
return false;
} }
void QRhiMetal::releaseCachedResources() void QRhiMetal::releaseCachedResources()
@ -595,6 +597,11 @@ void QRhiMetal::releaseCachedResources()
d->shaderCache.clear(); d->shaderCache.clear();
} }
bool QRhiMetal::isDeviceLost() const
{
return false;
}
QRhiRenderBuffer *QRhiMetal::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize, QRhiRenderBuffer *QRhiMetal::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
int sampleCount, QRhiRenderBuffer::Flags flags) int sampleCount, QRhiRenderBuffer::Flags flags)
{ {
@ -655,7 +662,7 @@ void QRhiMetal::enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD
{ {
QMetalBuffer *bufD = QRHI_RES(QMetalBuffer, b->u.ubuf.buf); QMetalBuffer *bufD = QRHI_RES(QMetalBuffer, b->u.ubuf.buf);
id<MTLBuffer> mtlbuf = bufD->d->buf[bufD->d->slotted ? currentFrameSlot : 0]; id<MTLBuffer> mtlbuf = bufD->d->buf[bufD->d->slotted ? currentFrameSlot : 0];
uint offset = b->u.ubuf.offset; uint offset = uint(b->u.ubuf.offset);
for (int i = 0; i < dynamicOffsetCount; ++i) { for (int i = 0; i < dynamicOffsetCount; ++i) {
const QRhiCommandBuffer::DynamicOffset &dynOfs(dynamicOffsets[i]); const QRhiCommandBuffer::DynamicOffset &dynOfs(dynamicOffsets[i]);
if (dynOfs.first == b->binding) { if (dynOfs.first == b->binding) {
@ -719,7 +726,7 @@ void QRhiMetal::enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD
{ {
QMetalBuffer *bufD = QRHI_RES(QMetalBuffer, b->u.sbuf.buf); QMetalBuffer *bufD = QRHI_RES(QMetalBuffer, b->u.sbuf.buf);
id<MTLBuffer> mtlbuf = bufD->d->buf[0]; id<MTLBuffer> mtlbuf = bufD->d->buf[0];
uint offset = b->u.sbuf.offset; uint offset = uint(b->u.sbuf.offset);
if (b->stage.testFlag(QRhiShaderResourceBinding::VertexStage)) { if (b->stage.testFlag(QRhiShaderResourceBinding::VertexStage)) {
res[0].buffers.feed(b->binding, mtlbuf); res[0].buffers.feed(b->binding, mtlbuf);
res[0].bufferOffsets.feed(b->binding, offset); res[0].bufferOffsets.feed(b->binding, offset);
@ -751,17 +758,17 @@ void QRhiMetal::enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD
case 0: case 0:
[cbD->d->currentRenderPassEncoder setVertexBuffers: bufferBatch.resources.constData() [cbD->d->currentRenderPassEncoder setVertexBuffers: bufferBatch.resources.constData()
offsets: offsetBatch.resources.constData() offsets: offsetBatch.resources.constData()
withRange: NSMakeRange(bufferBatch.startBinding, bufferBatch.resources.count())]; withRange: NSMakeRange(bufferBatch.startBinding, NSUInteger(bufferBatch.resources.count()))];
break; break;
case 1: case 1:
[cbD->d->currentRenderPassEncoder setFragmentBuffers: bufferBatch.resources.constData() [cbD->d->currentRenderPassEncoder setFragmentBuffers: bufferBatch.resources.constData()
offsets: offsetBatch.resources.constData() offsets: offsetBatch.resources.constData()
withRange: NSMakeRange(bufferBatch.startBinding, bufferBatch.resources.count())]; withRange: NSMakeRange(bufferBatch.startBinding, NSUInteger(bufferBatch.resources.count()))];
break; break;
case 2: case 2:
[cbD->d->currentComputePassEncoder setBuffers: bufferBatch.resources.constData() [cbD->d->currentComputePassEncoder setBuffers: bufferBatch.resources.constData()
offsets: offsetBatch.resources.constData() offsets: offsetBatch.resources.constData()
withRange: NSMakeRange(bufferBatch.startBinding, bufferBatch.resources.count())]; withRange: NSMakeRange(bufferBatch.startBinding, NSUInteger(bufferBatch.resources.count()))];
break; break;
default: default:
Q_UNREACHABLE(); Q_UNREACHABLE();
@ -780,15 +787,15 @@ void QRhiMetal::enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD
switch (idx) { switch (idx) {
case 0: case 0:
[cbD->d->currentRenderPassEncoder setVertexTextures: batch.resources.constData() [cbD->d->currentRenderPassEncoder setVertexTextures: batch.resources.constData()
withRange: NSMakeRange(batch.startBinding, batch.resources.count())]; withRange: NSMakeRange(batch.startBinding, NSUInteger(batch.resources.count()))];
break; break;
case 1: case 1:
[cbD->d->currentRenderPassEncoder setFragmentTextures: batch.resources.constData() [cbD->d->currentRenderPassEncoder setFragmentTextures: batch.resources.constData()
withRange: NSMakeRange(batch.startBinding, batch.resources.count())]; withRange: NSMakeRange(batch.startBinding, NSUInteger(batch.resources.count()))];
break; break;
case 2: case 2:
[cbD->d->currentComputePassEncoder setTextures: batch.resources.constData() [cbD->d->currentComputePassEncoder setTextures: batch.resources.constData()
withRange: NSMakeRange(batch.startBinding, batch.resources.count())]; withRange: NSMakeRange(batch.startBinding, NSUInteger(batch.resources.count()))];
break; break;
default: default:
Q_UNREACHABLE(); Q_UNREACHABLE();
@ -800,15 +807,15 @@ void QRhiMetal::enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD
switch (idx) { switch (idx) {
case 0: case 0:
[cbD->d->currentRenderPassEncoder setVertexSamplerStates: batch.resources.constData() [cbD->d->currentRenderPassEncoder setVertexSamplerStates: batch.resources.constData()
withRange: NSMakeRange(batch.startBinding, batch.resources.count())]; withRange: NSMakeRange(batch.startBinding, NSUInteger(batch.resources.count()))];
break; break;
case 1: case 1:
[cbD->d->currentRenderPassEncoder setFragmentSamplerStates: batch.resources.constData() [cbD->d->currentRenderPassEncoder setFragmentSamplerStates: batch.resources.constData()
withRange: NSMakeRange(batch.startBinding, batch.resources.count())]; withRange: NSMakeRange(batch.startBinding, NSUInteger(batch.resources.count()))];
break; break;
case 2: case 2:
[cbD->d->currentComputePassEncoder setSamplerStates: batch.resources.constData() [cbD->d->currentComputePassEncoder setSamplerStates: batch.resources.constData()
withRange: NSMakeRange(batch.startBinding, batch.resources.count())]; withRange: NSMakeRange(batch.startBinding, NSUInteger(batch.resources.count()))];
break; break;
default: default:
Q_UNREACHABLE(); Q_UNREACHABLE();
@ -1006,7 +1013,7 @@ void QRhiMetal::setVertexInput(QRhiCommandBuffer *cb,
[cbD->d->currentRenderPassEncoder setVertexBuffers: [cbD->d->currentRenderPassEncoder setVertexBuffers:
bufferBatch.resources.constData() bufferBatch.resources.constData()
offsets: offsetBatch.resources.constData() offsets: offsetBatch.resources.constData()
withRange: NSMakeRange(firstVertexBinding + bufferBatch.startBinding, bufferBatch.resources.count())]; withRange: NSMakeRange(uint(firstVertexBinding) + bufferBatch.startBinding, NSUInteger(bufferBatch.resources.count()))];
} }
} }
@ -1067,21 +1074,21 @@ void QRhiMetal::setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport)
return; return;
MTLViewport vp; MTLViewport vp;
vp.originX = x; vp.originX = double(x);
vp.originY = y; vp.originY = double(y);
vp.width = w; vp.width = double(w);
vp.height = h; vp.height = double(h);
vp.znear = viewport.minDepth(); vp.znear = double(viewport.minDepth());
vp.zfar = viewport.maxDepth(); vp.zfar = double(viewport.maxDepth());
[cbD->d->currentRenderPassEncoder setViewport: vp]; [cbD->d->currentRenderPassEncoder setViewport: vp];
if (!QRHI_RES(QMetalGraphicsPipeline, cbD->currentGraphicsPipeline)->m_flags.testFlag(QRhiGraphicsPipeline::UsesScissor)) { if (!QRHI_RES(QMetalGraphicsPipeline, cbD->currentGraphicsPipeline)->m_flags.testFlag(QRhiGraphicsPipeline::UsesScissor)) {
MTLScissorRect s; MTLScissorRect s;
s.x = x; s.x = NSUInteger(x);
s.y = y; s.y = NSUInteger(y);
s.width = w; s.width = NSUInteger(w);
s.height = h; s.height = NSUInteger(h);
[cbD->d->currentRenderPassEncoder setScissorRect: s]; [cbD->d->currentRenderPassEncoder setScissorRect: s];
} }
} }
@ -1099,10 +1106,10 @@ void QRhiMetal::setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor)
return; return;
MTLScissorRect s; MTLScissorRect s;
s.x = x; s.x = NSUInteger(x);
s.y = y; s.y = NSUInteger(y);
s.width = w; s.width = NSUInteger(w);
s.height = h; s.height = NSUInteger(h);
[cbD->d->currentRenderPassEncoder setScissorRect: s]; [cbD->d->currentRenderPassEncoder setScissorRect: s];
} }
@ -1112,7 +1119,8 @@ void QRhiMetal::setBlendConstants(QRhiCommandBuffer *cb, const QColor &c)
QMetalCommandBuffer *cbD = QRHI_RES(QMetalCommandBuffer, cb); QMetalCommandBuffer *cbD = QRHI_RES(QMetalCommandBuffer, cb);
Q_ASSERT(cbD->recordingPass == QMetalCommandBuffer::RenderPass); Q_ASSERT(cbD->recordingPass == QMetalCommandBuffer::RenderPass);
[cbD->d->currentRenderPassEncoder setBlendColorRed: c.redF() green: c.greenF() blue: c.blueF() alpha: c.alphaF()]; [cbD->d->currentRenderPassEncoder setBlendColorRed: float(c.redF())
green: float(c.greenF()) blue: float(c.blueF()) alpha: float(c.alphaF())];
} }
void QRhiMetal::setStencilRef(QRhiCommandBuffer *cb, quint32 refValue) void QRhiMetal::setStencilRef(QRhiCommandBuffer *cb, quint32 refValue)
@ -1144,7 +1152,7 @@ void QRhiMetal::drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount,
return; return;
const quint32 indexOffset = cbD->currentIndexOffset + firstIndex * (cbD->currentIndexFormat == QRhiCommandBuffer::IndexUInt16 ? 2 : 4); const quint32 indexOffset = cbD->currentIndexOffset + firstIndex * (cbD->currentIndexFormat == QRhiCommandBuffer::IndexUInt16 ? 2 : 4);
Q_ASSERT(indexOffset == aligned(indexOffset, 4)); Q_ASSERT(indexOffset == aligned<quint32>(indexOffset, 4));
QMetalBuffer *ibufD = QRHI_RES(QMetalBuffer, cbD->currentIndexBuffer); QMetalBuffer *ibufD = QRHI_RES(QMetalBuffer, cbD->currentIndexBuffer);
id<MTLBuffer> mtlbuf = ibufD->d->buf[ibufD->d->slotted ? currentFrameSlot : 0]; id<MTLBuffer> mtlbuf = ibufD->d->buf[ibufD->d->slotted ? currentFrameSlot : 0];
@ -1402,7 +1410,7 @@ MTLRenderPassDescriptor *QRhiMetalData::createDefaultRenderPass(bool hasDepthSte
MTLClearColor c = MTLClearColorMake(colorClearValue.redF(), colorClearValue.greenF(), colorClearValue.blueF(), MTLClearColor c = MTLClearColorMake(colorClearValue.redF(), colorClearValue.greenF(), colorClearValue.blueF(),
colorClearValue.alphaF()); colorClearValue.alphaF());
for (int i = 0; i < colorAttCount; ++i) { for (uint i = 0; i < uint(colorAttCount); ++i) {
rp.colorAttachments[i].loadAction = MTLLoadActionClear; rp.colorAttachments[i].loadAction = MTLLoadActionClear;
rp.colorAttachments[i].storeAction = MTLStoreActionStore; rp.colorAttachments[i].storeAction = MTLStoreActionStore;
rp.colorAttachments[i].clearColor = c; rp.colorAttachments[i].clearColor = c;
@ -1413,7 +1421,7 @@ MTLRenderPassDescriptor *QRhiMetalData::createDefaultRenderPass(bool hasDepthSte
rp.depthAttachment.storeAction = MTLStoreActionDontCare; rp.depthAttachment.storeAction = MTLStoreActionDontCare;
rp.stencilAttachment.loadAction = MTLLoadActionClear; rp.stencilAttachment.loadAction = MTLLoadActionClear;
rp.stencilAttachment.storeAction = MTLStoreActionDontCare; rp.stencilAttachment.storeAction = MTLStoreActionDontCare;
rp.depthAttachment.clearDepth = depthStencilClearValue.depthClearValue(); rp.depthAttachment.clearDepth = double(depthStencilClearValue.depthClearValue());
rp.stencilAttachment.clearStencil = depthStencilClearValue.stencilClearValue(); rp.stencilAttachment.clearStencil = depthStencilClearValue.stencilClearValue();
} }
@ -1426,7 +1434,7 @@ qsizetype QRhiMetal::subresUploadByteSize(const QRhiTextureSubresourceUploadDesc
const qsizetype imageSizeBytes = subresDesc.image().isNull() ? const qsizetype imageSizeBytes = subresDesc.image().isNull() ?
subresDesc.data().size() : subresDesc.image().sizeInBytes(); subresDesc.data().size() : subresDesc.image().sizeInBytes();
if (imageSizeBytes > 0) if (imageSizeBytes > 0)
size += aligned(imageSizeBytes, QRhiMetalData::TEXBUF_ALIGN); size += aligned<qsizetype>(imageSizeBytes, QRhiMetalData::TEXBUF_ALIGN);
return size; return size;
} }
@ -1454,31 +1462,31 @@ void QRhiMetal::enqueueSubresUpload(QMetalTexture *texD, void *mp, void *blitEnc
h = subresDesc.sourceSize().height(); h = subresDesc.sourceSize().height();
} }
if (img.depth() == 32) { if (img.depth() == 32) {
memcpy(reinterpret_cast<char *>(mp) + *curOfs, img.constBits(), fullImageSizeBytes); memcpy(reinterpret_cast<char *>(mp) + *curOfs, img.constBits(), size_t(fullImageSizeBytes));
srcOffset = sy * bpl + sx * 4; srcOffset = sy * bpl + sx * 4;
// bpl remains set to the original image's row stride // bpl remains set to the original image's row stride
} else { } else {
img = img.copy(sx, sy, w, h); img = img.copy(sx, sy, w, h);
bpl = img.bytesPerLine(); bpl = img.bytesPerLine();
Q_ASSERT(img.sizeInBytes() <= fullImageSizeBytes); Q_ASSERT(img.sizeInBytes() <= fullImageSizeBytes);
memcpy(reinterpret_cast<char *>(mp) + *curOfs, img.constBits(), img.sizeInBytes()); memcpy(reinterpret_cast<char *>(mp) + *curOfs, img.constBits(), size_t(img.sizeInBytes()));
} }
} else { } else {
memcpy(reinterpret_cast<char *>(mp) + *curOfs, img.constBits(), fullImageSizeBytes); memcpy(reinterpret_cast<char *>(mp) + *curOfs, img.constBits(), size_t(fullImageSizeBytes));
} }
[blitEnc copyFromBuffer: texD->d->stagingBuf[currentFrameSlot] [blitEnc copyFromBuffer: texD->d->stagingBuf[currentFrameSlot]
sourceOffset: *curOfs + srcOffset sourceOffset: NSUInteger(*curOfs + srcOffset)
sourceBytesPerRow: bpl sourceBytesPerRow: NSUInteger(bpl)
sourceBytesPerImage: 0 sourceBytesPerImage: 0
sourceSize: MTLSizeMake(w, h, 1) sourceSize: MTLSizeMake(NSUInteger(w), NSUInteger(h), 1)
toTexture: texD->d->tex toTexture: texD->d->tex
destinationSlice: layer destinationSlice: NSUInteger(layer)
destinationLevel: level destinationLevel: NSUInteger(level)
destinationOrigin: MTLOriginMake(dp.x(), dp.y(), 0) destinationOrigin: MTLOriginMake(NSUInteger(dp.x()), NSUInteger(dp.y()), 0)
options: MTLBlitOptionNone]; options: MTLBlitOptionNone];
*curOfs += aligned(fullImageSizeBytes, QRhiMetalData::TEXBUF_ALIGN); *curOfs += aligned<qsizetype>(fullImageSizeBytes, QRhiMetalData::TEXBUF_ALIGN);
} else if (!rawData.isEmpty() && isCompressedFormat(texD->m_format)) { } else if (!rawData.isEmpty() && isCompressedFormat(texD->m_format)) {
const QSize subresSize = q->sizeForMipLevel(level, texD->m_pixelSize); const QSize subresSize = q->sizeForMipLevel(level, texD->m_pixelSize);
const int subresw = subresSize.width(); const int subresw = subresSize.width();
@ -1503,17 +1511,17 @@ void QRhiMetal::enqueueSubresUpload(QMetalTexture *texD, void *mp, void *blitEnc
if (dy + h != subresh) if (dy + h != subresh)
h = aligned(h, blockDim.height()); h = aligned(h, blockDim.height());
memcpy(reinterpret_cast<char *>(mp) + *curOfs, rawData.constData(), rawData.size()); memcpy(reinterpret_cast<char *>(mp) + *curOfs, rawData.constData(), size_t(rawData.size()));
[blitEnc copyFromBuffer: texD->d->stagingBuf[currentFrameSlot] [blitEnc copyFromBuffer: texD->d->stagingBuf[currentFrameSlot]
sourceOffset: *curOfs sourceOffset: NSUInteger(*curOfs)
sourceBytesPerRow: bpl sourceBytesPerRow: bpl
sourceBytesPerImage: 0 sourceBytesPerImage: 0
sourceSize: MTLSizeMake(w, h, 1) sourceSize: MTLSizeMake(NSUInteger(w), NSUInteger(h), 1)
toTexture: texD->d->tex toTexture: texD->d->tex
destinationSlice: layer destinationSlice: NSUInteger(layer)
destinationLevel: level destinationLevel: NSUInteger(level)
destinationOrigin: MTLOriginMake(dx, dy, 0) destinationOrigin: MTLOriginMake(NSUInteger(dx), NSUInteger(dy), 0)
options: MTLBlitOptionNone]; options: MTLBlitOptionNone];
*curOfs += aligned(rawData.size(), QRhiMetalData::TEXBUF_ALIGN); *curOfs += aligned(rawData.size(), QRhiMetalData::TEXBUF_ALIGN);
@ -1532,17 +1540,17 @@ void QRhiMetal::enqueueSubresUpload(QMetalTexture *texD, void *mp, void *blitEnc
quint32 bpl = 0; quint32 bpl = 0;
textureFormatInfo(texD->m_format, QSize(w, h), &bpl, nullptr); textureFormatInfo(texD->m_format, QSize(w, h), &bpl, nullptr);
memcpy(reinterpret_cast<char *>(mp) + *curOfs, rawData.constData(), rawData.size()); memcpy(reinterpret_cast<char *>(mp) + *curOfs, rawData.constData(), size_t(rawData.size()));
[blitEnc copyFromBuffer: texD->d->stagingBuf[currentFrameSlot] [blitEnc copyFromBuffer: texD->d->stagingBuf[currentFrameSlot]
sourceOffset: *curOfs sourceOffset: NSUInteger(*curOfs)
sourceBytesPerRow: bpl sourceBytesPerRow: bpl
sourceBytesPerImage: 0 sourceBytesPerImage: 0
sourceSize: MTLSizeMake(w, h, 1) sourceSize: MTLSizeMake(NSUInteger(w), NSUInteger(h), 1)
toTexture: texD->d->tex toTexture: texD->d->tex
destinationSlice: layer destinationSlice: NSUInteger(layer)
destinationLevel: level destinationLevel: NSUInteger(level)
destinationOrigin: MTLOriginMake(dp.x(), dp.y(), 0) destinationOrigin: MTLOriginMake(NSUInteger(dp.x()), NSUInteger(dp.y()), 0)
options: MTLBlitOptionNone]; options: MTLBlitOptionNone];
*curOfs += aligned(rawData.size(), QRhiMetalData::TEXBUF_ALIGN); *curOfs += aligned(rawData.size(), QRhiMetalData::TEXBUF_ALIGN);
@ -1596,9 +1604,9 @@ void QRhiMetal::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
ensureBlit(); ensureBlit();
Q_ASSERT(!utexD->d->stagingBuf[currentFrameSlot]); Q_ASSERT(!utexD->d->stagingBuf[currentFrameSlot]);
utexD->d->stagingBuf[currentFrameSlot] = [d->dev newBufferWithLength: stagingSize utexD->d->stagingBuf[currentFrameSlot] = [d->dev newBufferWithLength: NSUInteger(stagingSize)
options: MTLResourceStorageModeShared]; options: MTLResourceStorageModeShared];
QRHI_PROF_F(newTextureStagingArea(utexD, currentFrameSlot, stagingSize)); QRHI_PROF_F(newTextureStagingArea(utexD, currentFrameSlot, quint32(stagingSize)));
void *mp = [utexD->d->stagingBuf[currentFrameSlot] contents]; void *mp = [utexD->d->stagingBuf[currentFrameSlot] contents];
qsizetype curOfs = 0; qsizetype curOfs = 0;
@ -1628,14 +1636,14 @@ void QRhiMetal::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
ensureBlit(); ensureBlit();
[blitEnc copyFromTexture: srcD->d->tex [blitEnc copyFromTexture: srcD->d->tex
sourceSlice: u.copy.desc.sourceLayer() sourceSlice: NSUInteger(u.copy.desc.sourceLayer())
sourceLevel: u.copy.desc.sourceLevel() sourceLevel: NSUInteger(u.copy.desc.sourceLevel())
sourceOrigin: MTLOriginMake(sp.x(), sp.y(), 0) sourceOrigin: MTLOriginMake(NSUInteger(sp.x()), NSUInteger(sp.y()), 0)
sourceSize: MTLSizeMake(size.width(), size.height(), 1) sourceSize: MTLSizeMake(NSUInteger(size.width()), NSUInteger(size.height()), 1)
toTexture: dstD->d->tex toTexture: dstD->d->tex
destinationSlice: u.copy.desc.destinationLayer() destinationSlice: NSUInteger(u.copy.desc.destinationLayer())
destinationLevel: u.copy.desc.destinationLevel() destinationLevel: NSUInteger(u.copy.desc.destinationLevel())
destinationOrigin: MTLOriginMake(dp.x(), dp.y(), 0)]; destinationOrigin: MTLOriginMake(NSUInteger(dp.x()), NSUInteger(dp.y()), 0)];
srcD->lastActiveFrameSlot = dstD->lastActiveFrameSlot = currentFrameSlot; srcD->lastActiveFrameSlot = dstD->lastActiveFrameSlot = currentFrameSlot;
} else if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::Read) { } else if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::Read) {
@ -1675,16 +1683,16 @@ void QRhiMetal::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
textureFormatInfo(aRb.format, aRb.pixelSize, &bpl, &aRb.bufSize); textureFormatInfo(aRb.format, aRb.pixelSize, &bpl, &aRb.bufSize);
aRb.buf = [d->dev newBufferWithLength: aRb.bufSize options: MTLResourceStorageModeShared]; aRb.buf = [d->dev newBufferWithLength: aRb.bufSize options: MTLResourceStorageModeShared];
QRHI_PROF_F(newReadbackBuffer(quint64(quintptr(aRb.buf)), QRHI_PROF_F(newReadbackBuffer(qint64(qintptr(aRb.buf)),
texD ? static_cast<QRhiResource *>(texD) : static_cast<QRhiResource *>(swapChainD), texD ? static_cast<QRhiResource *>(texD) : static_cast<QRhiResource *>(swapChainD),
aRb.bufSize)); aRb.bufSize));
ensureBlit(); ensureBlit();
[blitEnc copyFromTexture: src [blitEnc copyFromTexture: src
sourceSlice: u.read.rb.layer() sourceSlice: NSUInteger(u.read.rb.layer())
sourceLevel: u.read.rb.level() sourceLevel: NSUInteger(u.read.rb.level())
sourceOrigin: MTLOriginMake(0, 0, 0) sourceOrigin: MTLOriginMake(0, 0, 0)
sourceSize: MTLSizeMake(srcSize.width(), srcSize.height(), 1) sourceSize: MTLSizeMake(NSUInteger(srcSize.width()), NSUInteger(srcSize.height()), 1)
toBuffer: aRb.buf toBuffer: aRb.buf
destinationOffset: 0 destinationOffset: 0
destinationBytesPerRow: bpl destinationBytesPerRow: bpl
@ -1722,14 +1730,14 @@ void QRhiMetal::executeBufferHostWritesForCurrentFrame(QMetalBuffer *bufD)
int changeEnd = -1; int changeEnd = -1;
for (const QRhiResourceUpdateBatchPrivate::DynamicBufferUpdate &u : updates) { for (const QRhiResourceUpdateBatchPrivate::DynamicBufferUpdate &u : updates) {
Q_ASSERT(bufD == QRHI_RES(QMetalBuffer, u.buf)); Q_ASSERT(bufD == QRHI_RES(QMetalBuffer, u.buf));
memcpy(static_cast<char *>(p) + u.offset, u.data.constData(), u.data.size()); memcpy(static_cast<char *>(p) + u.offset, u.data.constData(), size_t(u.data.size()));
if (changeBegin == -1 || u.offset < changeBegin) if (changeBegin == -1 || u.offset < changeBegin)
changeBegin = u.offset; changeBegin = u.offset;
if (changeEnd == -1 || u.offset + u.data.size() > changeEnd) if (changeEnd == -1 || u.offset + u.data.size() > changeEnd)
changeEnd = u.offset + u.data.size(); changeEnd = u.offset + u.data.size();
} }
if (changeBegin >= 0 && bufD->d->managed) if (changeBegin >= 0 && bufD->d->managed)
[bufD->d->buf[idx] didModifyRange: NSMakeRange(changeBegin, changeEnd - changeBegin)]; [bufD->d->buf[idx] didModifyRange: NSMakeRange(NSUInteger(changeBegin), NSUInteger(changeEnd - changeBegin))];
updates.clear(); updates.clear();
} }
@ -1786,7 +1794,7 @@ void QRhiMetal::beginPass(QRhiCommandBuffer *cb,
rtD = rtTex->d; rtD = rtTex->d;
cbD->d->currentPassRpDesc = d->createDefaultRenderPass(rtD->dsAttCount, colorClearValue, depthStencilClearValue, rtD->colorAttCount); cbD->d->currentPassRpDesc = d->createDefaultRenderPass(rtD->dsAttCount, colorClearValue, depthStencilClearValue, rtD->colorAttCount);
if (rtTex->m_flags.testFlag(QRhiTextureRenderTarget::PreserveColorContents)) { if (rtTex->m_flags.testFlag(QRhiTextureRenderTarget::PreserveColorContents)) {
for (int i = 0; i < rtD->colorAttCount; ++i) for (uint i = 0; i < uint(rtD->colorAttCount); ++i)
cbD->d->currentPassRpDesc.colorAttachments[i].loadAction = MTLLoadActionLoad; cbD->d->currentPassRpDesc.colorAttachments[i].loadAction = MTLLoadActionLoad;
} }
if (rtD->dsAttCount && rtTex->m_flags.testFlag(QRhiTextureRenderTarget::PreserveDepthStencilContents)) { if (rtD->dsAttCount && rtTex->m_flags.testFlag(QRhiTextureRenderTarget::PreserveDepthStencilContents)) {
@ -1813,15 +1821,15 @@ void QRhiMetal::beginPass(QRhiCommandBuffer *cb,
break; break;
} }
for (int i = 0; i < rtD->colorAttCount; ++i) { for (uint i = 0; i < uint(rtD->colorAttCount); ++i) {
cbD->d->currentPassRpDesc.colorAttachments[i].texture = rtD->fb.colorAtt[i].tex; cbD->d->currentPassRpDesc.colorAttachments[i].texture = rtD->fb.colorAtt[i].tex;
cbD->d->currentPassRpDesc.colorAttachments[i].slice = rtD->fb.colorAtt[i].layer; cbD->d->currentPassRpDesc.colorAttachments[i].slice = NSUInteger(rtD->fb.colorAtt[i].layer);
cbD->d->currentPassRpDesc.colorAttachments[i].level = rtD->fb.colorAtt[i].level; cbD->d->currentPassRpDesc.colorAttachments[i].level = NSUInteger(rtD->fb.colorAtt[i].level);
if (rtD->fb.colorAtt[i].resolveTex) { if (rtD->fb.colorAtt[i].resolveTex) {
cbD->d->currentPassRpDesc.colorAttachments[i].storeAction = MTLStoreActionMultisampleResolve; cbD->d->currentPassRpDesc.colorAttachments[i].storeAction = MTLStoreActionMultisampleResolve;
cbD->d->currentPassRpDesc.colorAttachments[i].resolveTexture = rtD->fb.colorAtt[i].resolveTex; cbD->d->currentPassRpDesc.colorAttachments[i].resolveTexture = rtD->fb.colorAtt[i].resolveTex;
cbD->d->currentPassRpDesc.colorAttachments[i].resolveSlice = rtD->fb.colorAtt[i].resolveLayer; cbD->d->currentPassRpDesc.colorAttachments[i].resolveSlice = NSUInteger(rtD->fb.colorAtt[i].resolveLayer);
cbD->d->currentPassRpDesc.colorAttachments[i].resolveLevel = rtD->fb.colorAtt[i].resolveLevel; cbD->d->currentPassRpDesc.colorAttachments[i].resolveLevel = NSUInteger(rtD->fb.colorAtt[i].resolveLevel);
} }
} }
@ -1903,7 +1911,7 @@ void QRhiMetal::dispatch(QRhiCommandBuffer *cb, int x, int y, int z)
Q_ASSERT(cbD->recordingPass == QMetalCommandBuffer::ComputePass); Q_ASSERT(cbD->recordingPass == QMetalCommandBuffer::ComputePass);
QMetalComputePipeline *psD = QRHI_RES(QMetalComputePipeline, cbD->currentComputePipeline); QMetalComputePipeline *psD = QRHI_RES(QMetalComputePipeline, cbD->currentComputePipeline);
[cbD->d->currentComputePassEncoder dispatchThreadgroups: MTLSizeMake(x, y, z) [cbD->d->currentComputePassEncoder dispatchThreadgroups: MTLSizeMake(NSUInteger(x), NSUInteger(y), NSUInteger(z))
threadsPerThreadgroup: psD->d->localSize]; threadsPerThreadgroup: psD->d->localSize];
} }
@ -1971,12 +1979,12 @@ void QRhiMetal::finishActiveReadbacks(bool forced)
if (forced || currentFrameSlot == aRb.activeFrameSlot || aRb.activeFrameSlot < 0) { if (forced || currentFrameSlot == aRb.activeFrameSlot || aRb.activeFrameSlot < 0) {
aRb.result->format = aRb.format; aRb.result->format = aRb.format;
aRb.result->pixelSize = aRb.pixelSize; aRb.result->pixelSize = aRb.pixelSize;
aRb.result->data.resize(aRb.bufSize); aRb.result->data.resize(int(aRb.bufSize));
void *p = [aRb.buf contents]; void *p = [aRb.buf contents];
memcpy(aRb.result->data.data(), p, aRb.bufSize); memcpy(aRb.result->data.data(), p, aRb.bufSize);
[aRb.buf release]; [aRb.buf release];
QRHI_PROF_F(releaseReadbackBuffer(quint64(quintptr(aRb.buf)))); QRHI_PROF_F(releaseReadbackBuffer(qint64(qintptr(aRb.buf))));
if (aRb.result->completed) if (aRb.result->completed)
completedCallbacks.append(aRb.result->completed); completedCallbacks.append(aRb.result->completed);
@ -2035,8 +2043,8 @@ bool QMetalBuffer::build()
return false; return false;
} }
const int nonZeroSize = m_size <= 0 ? 256 : m_size; const uint nonZeroSize = m_size <= 0 ? 256 : uint(m_size);
const int roundedSize = m_usage.testFlag(QRhiBuffer::UniformBuffer) ? aligned(nonZeroSize, 256) : nonZeroSize; const uint roundedSize = m_usage.testFlag(QRhiBuffer::UniformBuffer) ? aligned<uint>(nonZeroSize, 256) : nonZeroSize;
d->managed = false; d->managed = false;
MTLResourceOptions opts = MTLResourceStorageModeShared; MTLResourceOptions opts = MTLResourceStorageModeShared;
@ -2123,10 +2131,10 @@ bool QMetalRenderBuffer::build()
MTLTextureDescriptor *desc = [[MTLTextureDescriptor alloc] init]; MTLTextureDescriptor *desc = [[MTLTextureDescriptor alloc] init];
desc.textureType = samples > 1 ? MTLTextureType2DMultisample : MTLTextureType2D; desc.textureType = samples > 1 ? MTLTextureType2DMultisample : MTLTextureType2D;
desc.width = m_pixelSize.width(); desc.width = NSUInteger(m_pixelSize.width());
desc.height = m_pixelSize.height(); desc.height = NSUInteger(m_pixelSize.height());
if (samples > 1) if (samples > 1)
desc.sampleCount = samples; desc.sampleCount = NSUInteger(samples);
desc.resourceOptions = MTLResourceStorageModePrivate; desc.resourceOptions = MTLResourceStorageModePrivate;
desc.usage = MTLTextureUsageRenderTarget; desc.usage = MTLTextureUsageRenderTarget;
@ -2393,11 +2401,11 @@ bool QMetalTexture::build()
else else
desc.textureType = samples > 1 ? MTLTextureType2DMultisample : MTLTextureType2D; desc.textureType = samples > 1 ? MTLTextureType2DMultisample : MTLTextureType2D;
desc.pixelFormat = d->format; desc.pixelFormat = d->format;
desc.width = size.width(); desc.width = NSUInteger(size.width());
desc.height = size.height(); desc.height = NSUInteger(size.height());
desc.mipmapLevelCount = mipLevelCount; desc.mipmapLevelCount = NSUInteger(mipLevelCount);
if (samples > 1) if (samples > 1)
desc.sampleCount = samples; desc.sampleCount = NSUInteger(samples);
desc.resourceOptions = MTLResourceStorageModePrivate; desc.resourceOptions = MTLResourceStorageModePrivate;
desc.storageMode = MTLStorageModePrivate; desc.storageMode = MTLStorageModePrivate;
desc.usage = MTLTextureUsageShaderRead; desc.usage = MTLTextureUsageShaderRead;
@ -2463,7 +2471,7 @@ id<MTLTexture> QMetalTextureData::viewForLevel(int level)
const MTLTextureType type = [tex textureType]; const MTLTextureType type = [tex textureType];
const bool isCube = q->m_flags.testFlag(QRhiTexture::CubeMap); const bool isCube = q->m_flags.testFlag(QRhiTexture::CubeMap);
id<MTLTexture> view = [tex newTextureViewWithPixelFormat: format textureType: type id<MTLTexture> view = [tex newTextureViewWithPixelFormat: format textureType: type
levels: NSMakeRange(level, 1) slices: NSMakeRange(0, isCube ? 6 : 1)]; levels: NSMakeRange(NSUInteger(level), 1) slices: NSMakeRange(0, isCube ? 6 : 1)];
perLevelViews[level] = view; perLevelViews[level] = view;
return view; return view;
@ -2673,13 +2681,13 @@ QRhiRenderPassDescriptor *QMetalTextureRenderTarget::newCompatibleRenderPassDesc
for (int i = 0, ie = colorAttachments.count(); i != ie; ++i) { for (int i = 0, ie = colorAttachments.count(); i != ie; ++i) {
QMetalTexture *texD = QRHI_RES(QMetalTexture, colorAttachments[i].texture()); QMetalTexture *texD = QRHI_RES(QMetalTexture, colorAttachments[i].texture());
QMetalRenderBuffer *rbD = QRHI_RES(QMetalRenderBuffer, colorAttachments[i].renderBuffer()); QMetalRenderBuffer *rbD = QRHI_RES(QMetalRenderBuffer, colorAttachments[i].renderBuffer());
rpD->colorFormat[i] = texD ? texD->d->format : rbD->d->format; rpD->colorFormat[i] = int(texD ? texD->d->format : rbD->d->format);
} }
if (m_desc.depthTexture()) if (m_desc.depthTexture())
rpD->dsFormat = QRHI_RES(QMetalTexture, m_desc.depthTexture())->d->format; rpD->dsFormat = int(QRHI_RES(QMetalTexture, m_desc.depthTexture())->d->format);
else if (m_desc.depthStencilBuffer()) else if (m_desc.depthStencilBuffer())
rpD->dsFormat = QRHI_RES(QMetalRenderBuffer, m_desc.depthStencilBuffer())->d->format; rpD->dsFormat = int(QRHI_RES(QMetalRenderBuffer, m_desc.depthStencilBuffer())->d->format);
return rpD; return rpD;
} }
@ -3079,7 +3087,7 @@ id<MTLLibrary> QRhiMetalData::createMetalLib(const QShader &shader, QShader::Var
QShaderCode mtllib = shader.shader({ QShader::MetalLibShader, 12, shaderVariant }); QShaderCode mtllib = shader.shader({ QShader::MetalLibShader, 12, shaderVariant });
if (!mtllib.shader().isEmpty()) { if (!mtllib.shader().isEmpty()) {
dispatch_data_t data = dispatch_data_create(mtllib.shader().constData(), dispatch_data_t data = dispatch_data_create(mtllib.shader().constData(),
mtllib.shader().size(), size_t(mtllib.shader().size()),
dispatch_get_global_queue(0, 0), dispatch_get_global_queue(0, 0),
DISPATCH_DATA_DESTRUCTOR_DEFAULT); DISPATCH_DATA_DESTRUCTOR_DEFAULT);
NSError *err = nil; NSError *err = nil;
@ -3139,19 +3147,19 @@ bool QMetalGraphicsPipeline::build()
MTLVertexDescriptor *inputLayout = [MTLVertexDescriptor vertexDescriptor]; MTLVertexDescriptor *inputLayout = [MTLVertexDescriptor vertexDescriptor];
const QVector<QRhiVertexInputAttribute> attributes = m_vertexInputLayout.attributes(); const QVector<QRhiVertexInputAttribute> attributes = m_vertexInputLayout.attributes();
for (const QRhiVertexInputAttribute &attribute : attributes) { for (const QRhiVertexInputAttribute &attribute : attributes) {
const int loc = attribute.location(); const uint loc = uint(attribute.location());
inputLayout.attributes[loc].format = toMetalAttributeFormat(attribute.format()); inputLayout.attributes[loc].format = toMetalAttributeFormat(attribute.format());
inputLayout.attributes[loc].offset = attribute.offset(); inputLayout.attributes[loc].offset = NSUInteger(attribute.offset());
inputLayout.attributes[loc].bufferIndex = firstVertexBinding + attribute.binding(); inputLayout.attributes[loc].bufferIndex = NSUInteger(firstVertexBinding + attribute.binding());
} }
const QVector<QRhiVertexInputBinding> bindings = m_vertexInputLayout.bindings(); const QVector<QRhiVertexInputBinding> bindings = m_vertexInputLayout.bindings();
for (int i = 0, ie = bindings.count(); i != ie; ++i) { for (int i = 0, ie = bindings.count(); i != ie; ++i) {
const QRhiVertexInputBinding &binding(bindings[i]); const QRhiVertexInputBinding &binding(bindings[i]);
const int layoutIdx = firstVertexBinding + i; const uint layoutIdx = uint(firstVertexBinding + i);
inputLayout.layouts[layoutIdx].stepFunction = inputLayout.layouts[layoutIdx].stepFunction =
binding.classification() == QRhiVertexInputBinding::PerInstance binding.classification() == QRhiVertexInputBinding::PerInstance
? MTLVertexStepFunctionPerInstance : MTLVertexStepFunctionPerVertex; ? MTLVertexStepFunctionPerInstance : MTLVertexStepFunctionPerVertex;
inputLayout.layouts[layoutIdx].stepRate = binding.instanceStepRate(); inputLayout.layouts[layoutIdx].stepRate = NSUInteger(binding.instanceStepRate());
inputLayout.layouts[layoutIdx].stride = binding.stride(); inputLayout.layouts[layoutIdx].stride = binding.stride();
} }
@ -3239,8 +3247,8 @@ bool QMetalGraphicsPipeline::build()
Q_ASSERT(m_targetBlends.count() == rpD->colorAttachmentCount Q_ASSERT(m_targetBlends.count() == rpD->colorAttachmentCount
|| (m_targetBlends.isEmpty() && rpD->colorAttachmentCount == 1)); || (m_targetBlends.isEmpty() && rpD->colorAttachmentCount == 1));
for (int i = 0, ie = m_targetBlends.count(); i != ie; ++i) { for (uint i = 0, ie = uint(m_targetBlends.count()); i != ie; ++i) {
const QRhiGraphicsPipeline::TargetBlend &b(m_targetBlends[i]); const QRhiGraphicsPipeline::TargetBlend &b(m_targetBlends[int(i)]);
rpDesc.colorAttachments[i].pixelFormat = MTLPixelFormat(rpD->colorFormat[i]); rpDesc.colorAttachments[i].pixelFormat = MTLPixelFormat(rpD->colorFormat[i]);
rpDesc.colorAttachments[i].blendingEnabled = b.enable; rpDesc.colorAttachments[i].blendingEnabled = b.enable;
rpDesc.colorAttachments[i].sourceRGBBlendFactor = toMetalBlendFactor(b.srcColor); rpDesc.colorAttachments[i].sourceRGBBlendFactor = toMetalBlendFactor(b.srcColor);
@ -3262,7 +3270,7 @@ bool QMetalGraphicsPipeline::build()
rpDesc.stencilAttachmentPixelFormat = fmt; rpDesc.stencilAttachmentPixelFormat = fmt;
} }
rpDesc.sampleCount = rhiD->effectiveSampleCount(m_sampleCount); rpDesc.sampleCount = NSUInteger(rhiD->effectiveSampleCount(m_sampleCount));
NSError *err = nil; NSError *err = nil;
d->ps = [rhiD->d->dev newRenderPipelineStateWithDescriptor: rpDesc error: &err]; d->ps = [rhiD->d->dev newRenderPipelineStateWithDescriptor: rpDesc error: &err];
@ -3517,7 +3525,7 @@ QSize QMetalSwapChain::surfacePixelSize()
CAMetalLayer *layer = (CAMetalLayer *) [v layer]; CAMetalLayer *layer = (CAMetalLayer *) [v layer];
if (layer) { if (layer) {
CGSize size = [layer drawableSize]; CGSize size = [layer drawableSize];
return QSize(size.width, size.height); return QSize(int(size.width), int(size.height));
} }
} }
return QSize(); return QSize();
@ -3532,7 +3540,7 @@ QRhiRenderPassDescriptor *QMetalSwapChain::newCompatibleRenderPassDescriptor()
rpD->colorAttachmentCount = 1; rpD->colorAttachmentCount = 1;
rpD->hasDepthStencil = m_depthStencil != nullptr; rpD->hasDepthStencil = m_depthStencil != nullptr;
rpD->colorFormat[0] = d->colorFormat; rpD->colorFormat[0] = int(d->colorFormat);
// m_depthStencil may not be built yet so cannot rely on computed fields in it // m_depthStencil may not be built yet so cannot rely on computed fields in it
rpD->dsFormat = rhiD->d->dev.depth24Stencil8PixelFormatSupported rpD->dsFormat = rhiD->d->dev.depth24Stencil8PixelFormatSupported
@ -3589,6 +3597,18 @@ bool QMetalSwapChain::buildOrResize()
} }
#endif #endif
if (m_flags.testFlag(SurfaceHasPreMulAlpha)) {
d->layer.opaque = NO;
} else if (m_flags.testFlag(SurfaceHasNonPreMulAlpha)) {
// The CoreAnimation compositor is said to expect premultiplied alpha,
// so this is then wrong when it comes to the blending operations but
// there's nothing we can do. Fortunately Qt Quick always outputs
// premultiplied alpha so it is not a problem there.
d->layer.opaque = NO;
} else {
d->layer.opaque = YES;
}
m_currentPixelSize = surfacePixelSize(); m_currentPixelSize = surfacePixelSize();
pixelSize = m_currentPixelSize; pixelSize = m_currentPixelSize;
@ -3616,7 +3636,7 @@ bool QMetalSwapChain::buildOrResize()
} }
rtWrapper.d->pixelSize = pixelSize; rtWrapper.d->pixelSize = pixelSize;
rtWrapper.d->dpr = window->devicePixelRatio(); rtWrapper.d->dpr = float(window->devicePixelRatio());
rtWrapper.d->sampleCount = samples; rtWrapper.d->sampleCount = samples;
rtWrapper.d->colorAttCount = 1; rtWrapper.d->colorAttCount = 1;
rtWrapper.d->dsAttCount = ds ? 1 : 0; rtWrapper.d->dsAttCount = ds ? 1 : 0;
@ -3627,9 +3647,9 @@ bool QMetalSwapChain::buildOrResize()
MTLTextureDescriptor *desc = [[MTLTextureDescriptor alloc] init]; MTLTextureDescriptor *desc = [[MTLTextureDescriptor alloc] init];
desc.textureType = MTLTextureType2DMultisample; desc.textureType = MTLTextureType2DMultisample;
desc.pixelFormat = d->colorFormat; desc.pixelFormat = d->colorFormat;
desc.width = pixelSize.width(); desc.width = NSUInteger(pixelSize.width());
desc.height = pixelSize.height(); desc.height = NSUInteger(pixelSize.height());
desc.sampleCount = samples; desc.sampleCount = NSUInteger(samples);
desc.resourceOptions = MTLResourceStorageModePrivate; desc.resourceOptions = MTLResourceStorageModePrivate;
desc.storageMode = MTLStorageModePrivate; desc.storageMode = MTLStorageModePrivate;
desc.usage = MTLTextureUsageRenderTarget; desc.usage = MTLTextureUsageRenderTarget;

View File

@ -416,8 +416,9 @@ public:
int resourceLimit(QRhi::ResourceLimit limit) const override; int resourceLimit(QRhi::ResourceLimit limit) const override;
const QRhiNativeHandles *nativeHandles() override; const QRhiNativeHandles *nativeHandles() override;
void sendVMemStatsToProfiler() override; void sendVMemStatsToProfiler() override;
void makeThreadLocalNativeContextCurrent() override; bool makeThreadLocalNativeContextCurrent() override;
void releaseCachedResources() override; void releaseCachedResources() override;
bool isDeviceLost() const override;
void executeDeferredReleases(bool forced = false); void executeDeferredReleases(bool forced = false);
void finishActiveReadbacks(bool forced = false); void finishActiveReadbacks(bool forced = false);

View File

@ -169,9 +169,10 @@ void QRhiNull::sendVMemStatsToProfiler()
// nothing to do here // nothing to do here
} }
void QRhiNull::makeThreadLocalNativeContextCurrent() bool QRhiNull::makeThreadLocalNativeContextCurrent()
{ {
// nothing to do here // not applicable
return false;
} }
void QRhiNull::releaseCachedResources() void QRhiNull::releaseCachedResources()
@ -179,6 +180,11 @@ void QRhiNull::releaseCachedResources()
// nothing to do here // nothing to do here
} }
bool QRhiNull::isDeviceLost() const
{
return false;
}
QRhiRenderBuffer *QRhiNull::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize, QRhiRenderBuffer *QRhiNull::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
int sampleCount, QRhiRenderBuffer::Flags flags) int sampleCount, QRhiRenderBuffer::Flags flags)
{ {

View File

@ -282,8 +282,9 @@ public:
int resourceLimit(QRhi::ResourceLimit limit) const override; int resourceLimit(QRhi::ResourceLimit limit) const override;
const QRhiNativeHandles *nativeHandles() override; const QRhiNativeHandles *nativeHandles() override;
void sendVMemStatsToProfiler() override; void sendVMemStatsToProfiler() override;
void makeThreadLocalNativeContextCurrent() override; bool makeThreadLocalNativeContextCurrent() override;
void releaseCachedResources() override; void releaseCachedResources() override;
bool isDeviceLost() const override;
QRhiNullNativeHandles nativeHandlesStruct; QRhiNullNativeHandles nativeHandlesStruct;
QRhiSwapChain *currentSwapChain = nullptr; QRhiSwapChain *currentSwapChain = nullptr;

View File

@ -319,7 +319,7 @@ void QRhiProfilerPrivate::writeFloat(const char *key, float f)
Q_ASSERT(key[0] == 'F'); Q_ASSERT(key[0] == 'F');
buf.append(key); buf.append(key);
buf.append(','); buf.append(',');
buf.append(QByteArray::number(f)); buf.append(QByteArray::number(double(f)));
buf.append(','); buf.append(',');
} }
@ -385,7 +385,7 @@ void QRhiProfilerPrivate::newRenderBuffer(QRhiRenderBuffer *rb, bool transientBa
const QRhiTexture::Format assumedFormat = type == QRhiRenderBuffer::DepthStencil ? QRhiTexture::D32F : QRhiTexture::RGBA8; const QRhiTexture::Format assumedFormat = type == QRhiRenderBuffer::DepthStencil ? QRhiTexture::D32F : QRhiTexture::RGBA8;
quint32 byteSize = rhiDWhenEnabled->approxByteSizeForTexture(assumedFormat, sz, 1, 1); quint32 byteSize = rhiDWhenEnabled->approxByteSizeForTexture(assumedFormat, sz, 1, 1);
if (sampleCount > 1) if (sampleCount > 1)
byteSize *= sampleCount; byteSize *= uint(sampleCount);
startEntry(QRhiProfiler::NewRenderBuffer, ts.elapsed(), rb); startEntry(QRhiProfiler::NewRenderBuffer, ts.elapsed(), rb);
writeInt("type", type); writeInt("type", type);
@ -416,7 +416,7 @@ void QRhiProfilerPrivate::newTexture(QRhiTexture *tex, bool owns, int mipCount,
const QSize sz = tex->pixelSize(); const QSize sz = tex->pixelSize();
quint32 byteSize = rhiDWhenEnabled->approxByteSizeForTexture(format, sz, mipCount, layerCount); quint32 byteSize = rhiDWhenEnabled->approxByteSizeForTexture(format, sz, mipCount, layerCount);
if (sampleCount > 1) if (sampleCount > 1)
byteSize *= sampleCount; byteSize *= uint(sampleCount);
startEntry(QRhiProfiler::NewTexture, ts.elapsed(), tex); startEntry(QRhiProfiler::NewTexture, ts.elapsed(), tex);
writeInt("width", sz.width()); writeInt("width", sz.width());
@ -467,7 +467,7 @@ void QRhiProfilerPrivate::resizeSwapChain(QRhiSwapChain *sc, int bufferCount, in
const QSize sz = sc->currentPixelSize(); const QSize sz = sc->currentPixelSize();
quint32 byteSize = rhiDWhenEnabled->approxByteSizeForTexture(QRhiTexture::BGRA8, sz, 1, 1); quint32 byteSize = rhiDWhenEnabled->approxByteSizeForTexture(QRhiTexture::BGRA8, sz, 1, 1);
byteSize = byteSize * bufferCount + byteSize * msaaBufferCount * sampleCount; byteSize = byteSize * uint(bufferCount) + byteSize * uint(msaaBufferCount) * uint(sampleCount);
startEntry(QRhiProfiler::ResizeSwapChain, ts.elapsed(), sc); startEntry(QRhiProfiler::ResizeSwapChain, ts.elapsed(), sc);
writeInt("width", sz.width()); writeInt("width", sz.width());
@ -569,7 +569,7 @@ void QRhiProfilerPrivate::swapChainFrameGpuTime(QRhiSwapChain *sc, float gpuTime
} }
} }
void QRhiProfilerPrivate::newReadbackBuffer(quint64 id, QRhiResource *src, quint32 size) void QRhiProfilerPrivate::newReadbackBuffer(qint64 id, QRhiResource *src, quint32 size)
{ {
if (!outputDevice) if (!outputDevice)
return; return;
@ -580,7 +580,7 @@ void QRhiProfilerPrivate::newReadbackBuffer(quint64 id, QRhiResource *src, quint
endEntry(); endEntry();
} }
void QRhiProfilerPrivate::releaseReadbackBuffer(quint64 id) void QRhiProfilerPrivate::releaseReadbackBuffer(qint64 id)
{ {
if (!outputDevice) if (!outputDevice)
return; return;
@ -590,7 +590,7 @@ void QRhiProfilerPrivate::releaseReadbackBuffer(quint64 id)
endEntry(); endEntry();
} }
void QRhiProfilerPrivate::vmemStat(int realAllocCount, int subAllocCount, quint32 totalSize, quint32 unusedSize) void QRhiProfilerPrivate::vmemStat(uint realAllocCount, uint subAllocCount, quint32 totalSize, quint32 unusedSize)
{ {
if (!outputDevice) if (!outputDevice)
return; return;

View File

@ -79,10 +79,10 @@ public:
void endSwapChainFrame(QRhiSwapChain *sc, int frameCount); void endSwapChainFrame(QRhiSwapChain *sc, int frameCount);
void swapChainFrameGpuTime(QRhiSwapChain *sc, float gpuTimeMs); void swapChainFrameGpuTime(QRhiSwapChain *sc, float gpuTimeMs);
void newReadbackBuffer(quint64 id, QRhiResource *src, quint32 size); void newReadbackBuffer(qint64 id, QRhiResource *src, quint32 size);
void releaseReadbackBuffer(quint64 id); void releaseReadbackBuffer(qint64 id);
void vmemStat(int realAllocCount, int subAllocCount, quint32 totalSize, quint32 unusedSize); void vmemStat(uint realAllocCount, uint subAllocCount, quint32 totalSize, quint32 unusedSize);
void startEntry(QRhiProfiler::StreamOp op, qint64 timestamp, QRhiResource *res); void startEntry(QRhiProfiler::StreamOp op, qint64 timestamp, QRhiResource *res);
void writeInt(const char *key, qint64 v); void writeInt(const char *key, qint64 v);

File diff suppressed because it is too large Load Diff

View File

@ -711,8 +711,9 @@ public:
int resourceLimit(QRhi::ResourceLimit limit) const override; int resourceLimit(QRhi::ResourceLimit limit) const override;
const QRhiNativeHandles *nativeHandles() override; const QRhiNativeHandles *nativeHandles() override;
void sendVMemStatsToProfiler() override; void sendVMemStatsToProfiler() override;
void makeThreadLocalNativeContextCurrent() override; bool makeThreadLocalNativeContextCurrent() override;
void releaseCachedResources() override; void releaseCachedResources() override;
bool isDeviceLost() const override;
VkResult createDescriptorPool(VkDescriptorPool *pool); VkResult createDescriptorPool(VkDescriptorPool *pool);
bool allocateDescriptorSet(VkDescriptorSetAllocateInfo *allocInfo, VkDescriptorSet *result, int *resultPoolIndex); bool allocateDescriptorSet(VkDescriptorSetAllocateInfo *allocInfo, VkDescriptorSet *result, int *resultPoolIndex);
@ -804,6 +805,7 @@ public:
VkDeviceSize ubufAlign; VkDeviceSize ubufAlign;
VkDeviceSize texbufAlign; VkDeviceSize texbufAlign;
bool hasWideLines = false; bool hasWideLines = false;
bool deviceLost = false;
bool debugMarkersAvailable = false; bool debugMarkersAvailable = false;
bool vertexAttribDivisorAvailable = false; bool vertexAttribDivisorAvailable = false;

Some files were not shown because too many files have changed in this diff Show More