Merge remote-tracking branch 'origin/5.14' into 5.15
Change-Id: Ie24be82ee70bf103c2664de1a42741979262b10c
This commit is contained in:
commit
1cfa636fe2
@ -48,12 +48,21 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
#include "mainwindow.h"
|
||||
#include "encodingdialog.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()
|
||||
{
|
||||
textEdit = new QPlainTextEdit;
|
||||
@ -146,14 +155,14 @@ void MainWindow::findCodecs()
|
||||
QTextCodec *codec = QTextCodec::codecForMib(mib);
|
||||
|
||||
QString sortKey = codec->name().toUpper();
|
||||
int rank;
|
||||
char rank;
|
||||
|
||||
if (sortKey.startsWith(QLatin1String("UTF-8"))) {
|
||||
rank = 1;
|
||||
} else if (sortKey.startsWith(QLatin1String("UTF-16"))) {
|
||||
rank = 2;
|
||||
} else if ((match = iso8859RegExp.match(sortKey)).hasMatch()) {
|
||||
if (match.captured(1).size() == 1)
|
||||
if (match.capturedRef(1).size() == 1)
|
||||
rank = 3;
|
||||
else
|
||||
rank = 4;
|
||||
@ -164,7 +173,8 @@ void MainWindow::findCodecs()
|
||||
|
||||
codecMap.insert(sortKey, codec);
|
||||
}
|
||||
codecs = codecMap.values();
|
||||
for (const auto &codec : qAsConst(codecMap))
|
||||
codecs += codec;
|
||||
}
|
||||
|
||||
void MainWindow::createMenus()
|
||||
|
@ -51,7 +51,7 @@
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include <QList>
|
||||
#include <QVector>
|
||||
#include <QMainWindow>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
@ -81,10 +81,10 @@ private:
|
||||
void findCodecs();
|
||||
void createMenus();
|
||||
|
||||
QList<QAction *> saveAsActs;
|
||||
QVector<QAction *> saveAsActs;
|
||||
QPlainTextEdit *textEdit;
|
||||
PreviewForm *previewForm;
|
||||
QList<QTextCodec *> codecs;
|
||||
QVector<QTextCodec *> codecs;
|
||||
EncodingDialog *m_encodingDialog = nullptr;
|
||||
};
|
||||
|
||||
|
@ -48,10 +48,19 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
#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
|
||||
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)
|
||||
{
|
||||
for (int i = 0, size = data.size(); i < size; ++i) {
|
||||
const char c = data.at(i);
|
||||
for (const char c : data) {
|
||||
switch (c) {
|
||||
case '\0':
|
||||
str << "\\0";
|
||||
@ -179,7 +187,7 @@ PreviewForm::PreviewForm(QWidget *parent)
|
||||
resize(screenGeometry.width() * 2 / 5, screenGeometry.height() / 2);
|
||||
}
|
||||
|
||||
void PreviewForm::setCodecList(const QList<QTextCodec *> &list)
|
||||
void PreviewForm::setCodecList(const QVector<QTextCodec *> &list)
|
||||
{
|
||||
encodingComboBox->clear();
|
||||
for (const QTextCodec *codec : list) {
|
||||
@ -226,10 +234,10 @@ void PreviewForm::updateTextEdit()
|
||||
statusLabel->setText(message);
|
||||
statusLabel->setStyleSheet(QStringLiteral("background-color: \"red\";"));
|
||||
} 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\";"));
|
||||
} 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());
|
||||
}
|
||||
if (success)
|
||||
|
@ -52,7 +52,7 @@
|
||||
#define PREVIEWFORM_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QList>
|
||||
#include <QVector>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QComboBox;
|
||||
@ -71,7 +71,7 @@ class PreviewForm : public QDialog
|
||||
public:
|
||||
explicit PreviewForm(QWidget *parent = nullptr);
|
||||
|
||||
void setCodecList(const QList<QTextCodec *> &list);
|
||||
void setCodecList(const QVector<QTextCodec *> &list);
|
||||
void setEncodedData(const QByteArray &data);
|
||||
QString decodedString() const { return decodedStr; }
|
||||
|
||||
|
@ -62,7 +62,7 @@
|
||||
class FileSystemModel : public QFileSystemModel
|
||||
{
|
||||
public:
|
||||
FileSystemModel(QObject *parent = 0);
|
||||
FileSystemModel(QObject *parent = nullptr);
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
};
|
||||
//! [0]
|
||||
|
@ -48,13 +48,28 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtWidgets>
|
||||
#include "fsmodel.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]
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
: QMainWindow(parent), completer(0), lineEdit(0)
|
||||
: QMainWindow(parent)
|
||||
{
|
||||
createMenu();
|
||||
|
||||
@ -64,8 +79,8 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
modelLabel->setText(tr("Model"));
|
||||
|
||||
modelCombo = new QComboBox;
|
||||
modelCombo->addItem(tr("QFileSytemModel"));
|
||||
modelCombo->addItem(tr("QFileSytemModel that shows full path"));
|
||||
modelCombo->addItem(tr("QFileSystemModel"));
|
||||
modelCombo->addItem(tr("QFileSystemModel that shows full path"));
|
||||
modelCombo->addItem(tr("Country list"));
|
||||
modelCombo->addItem(tr("Word list"));
|
||||
modelCombo->setCurrentIndex(0);
|
||||
@ -144,17 +159,17 @@ void MainWindow::createMenu()
|
||||
connect(aboutAct, &QAction::triggered, this, &MainWindow::about);
|
||||
connect(aboutQtAct, &QAction::triggered, qApp, &QApplication::aboutQt);
|
||||
|
||||
QMenu* fileMenu = menuBar()->addMenu(tr("File"));
|
||||
QMenu *fileMenu = menuBar()->addMenu(tr("File"));
|
||||
fileMenu->addAction(exitAction);
|
||||
|
||||
QMenu* helpMenu = menuBar()->addMenu(tr("About"));
|
||||
QMenu *helpMenu = menuBar()->addMenu(tr("About"));
|
||||
helpMenu->addAction(aboutAct);
|
||||
helpMenu->addAction(aboutQtAct);
|
||||
}
|
||||
//! [4]
|
||||
|
||||
//! [5]
|
||||
QAbstractItemModel *MainWindow::modelFromFile(const QString& fileName)
|
||||
QAbstractItemModel *MainWindow::modelFromFile(const QString &fileName)
|
||||
{
|
||||
QFile file(fileName);
|
||||
if (!file.open(QFile::ReadOnly))
|
||||
@ -170,7 +185,7 @@ QAbstractItemModel *MainWindow::modelFromFile(const QString& fileName)
|
||||
while (!file.atEnd()) {
|
||||
QByteArray line = file.readLine();
|
||||
if (!line.isEmpty())
|
||||
words << line.trimmed();
|
||||
words << QString::fromUtf8(line.trimmed());
|
||||
}
|
||||
|
||||
#ifndef QT_NO_CURSOR
|
||||
@ -191,8 +206,8 @@ QAbstractItemModel *MainWindow::modelFromFile(const QString& fileName)
|
||||
for (int i = 0; i < words.count(); ++i) {
|
||||
QModelIndex countryIdx = m->index(i, 0);
|
||||
QModelIndex symbolIdx = m->index(i, 1);
|
||||
QString country = words[i].mid(0, words[i].length() - 2).trimmed();
|
||||
QString symbol = words[i].right(2);
|
||||
QString country = words.at(i).mid(0, words[i].length() - 2).trimmed();
|
||||
QString symbol = words.at(i).right(2);
|
||||
m->setData(countryIdx, country);
|
||||
m->setData(symbolIdx, symbol);
|
||||
}
|
||||
@ -233,7 +248,7 @@ void MainWindow::changeModel()
|
||||
case 0:
|
||||
{ // Unsorted QFileSystemModel
|
||||
QFileSystemModel *fsModel = new QFileSystemModel(completer);
|
||||
fsModel->setRootPath("");
|
||||
fsModel->setRootPath(QString());
|
||||
completer->setModel(fsModel);
|
||||
contentsLabel->setText(tr("Enter file path"));
|
||||
}
|
||||
@ -243,7 +258,7 @@ void MainWindow::changeModel()
|
||||
{ // FileSystemModel that shows full paths
|
||||
FileSystemModel *fsModel = new FileSystemModel(completer);
|
||||
completer->setModel(fsModel);
|
||||
fsModel->setRootPath("");
|
||||
fsModel->setRootPath(QString());
|
||||
contentsLabel->setText(tr("Enter file path"));
|
||||
}
|
||||
break;
|
||||
|
@ -59,7 +59,6 @@ class QComboBox;
|
||||
class QCompleter;
|
||||
class QLabel;
|
||||
class QLineEdit;
|
||||
class QProgressBar;
|
||||
class QCheckBox;
|
||||
class QSpinBox;
|
||||
QT_END_NAMESPACE
|
||||
@ -70,7 +69,7 @@ class MainWindow : public QMainWindow
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MainWindow(QWidget *parent = 0);
|
||||
MainWindow(QWidget *parent = nullptr);
|
||||
|
||||
private slots:
|
||||
void about();
|
||||
@ -83,16 +82,16 @@ private slots:
|
||||
//! [1]
|
||||
private:
|
||||
void createMenu();
|
||||
QAbstractItemModel *modelFromFile(const QString& fileName);
|
||||
QAbstractItemModel *modelFromFile(const QString &fileName);
|
||||
|
||||
QComboBox *caseCombo;
|
||||
QComboBox *modeCombo;
|
||||
QComboBox *modelCombo;
|
||||
QSpinBox *maxVisibleSpinBox;
|
||||
QCheckBox *wrapCheckBox;
|
||||
QCompleter *completer;
|
||||
QLabel *contentsLabel;
|
||||
QLineEdit *lineEdit;
|
||||
QComboBox *caseCombo = nullptr;
|
||||
QComboBox *modeCombo = nullptr;
|
||||
QComboBox *modelCombo = nullptr;
|
||||
QSpinBox *maxVisibleSpinBox = nullptr;
|
||||
QCheckBox *wrapCheckBox = nullptr;
|
||||
QCompleter *completer = nullptr;
|
||||
QLabel *contentsLabel = nullptr;
|
||||
QLineEdit *lineEdit = nullptr;
|
||||
};
|
||||
//! [1]
|
||||
|
||||
|
@ -48,13 +48,20 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtWidgets>
|
||||
#include "mainwindow.h"
|
||||
#include "textedit.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QApplication>
|
||||
#include <QCompleter>
|
||||
#include <QFile>
|
||||
#include <QMenuBar>
|
||||
#include <QMessageBox>
|
||||
#include <QStringListModel>
|
||||
|
||||
//! [0]
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
: QMainWindow(parent), completer(0)
|
||||
: QMainWindow(parent)
|
||||
{
|
||||
createMenu();
|
||||
|
||||
@ -83,10 +90,10 @@ void MainWindow::createMenu()
|
||||
connect(aboutAct, &QAction::triggered, this, &MainWindow::about);
|
||||
connect(aboutQtAct, &QAction::triggered, qApp, &QApplication::aboutQt);
|
||||
|
||||
QMenu* fileMenu = menuBar()->addMenu(tr("File"));
|
||||
QMenu *fileMenu = menuBar()->addMenu(tr("File"));
|
||||
fileMenu->addAction(exitAction);
|
||||
|
||||
QMenu* helpMenu = menuBar()->addMenu(tr("About"));
|
||||
QMenu *helpMenu = menuBar()->addMenu(tr("About"));
|
||||
helpMenu->addAction(aboutAct);
|
||||
helpMenu->addAction(aboutQtAct);
|
||||
}
|
||||
@ -107,7 +114,7 @@ QAbstractItemModel *MainWindow::modelFromFile(const QString& fileName)
|
||||
while (!file.atEnd()) {
|
||||
QByteArray line = file.readLine();
|
||||
if (!line.isEmpty())
|
||||
words << line.trimmed();
|
||||
words << QString::fromUtf8(line.trimmed());
|
||||
}
|
||||
|
||||
#ifndef QT_NO_CURSOR
|
||||
|
@ -55,11 +55,7 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QAbstractItemModel;
|
||||
class QComboBox;
|
||||
class QCompleter;
|
||||
class QLabel;
|
||||
class QLineEdit;
|
||||
class QProgressBar;
|
||||
QT_END_NAMESPACE
|
||||
class TextEdit;
|
||||
|
||||
@ -69,7 +65,7 @@ class MainWindow : public QMainWindow
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MainWindow(QWidget *parent = 0);
|
||||
MainWindow(QWidget *parent = nullptr);
|
||||
|
||||
private slots:
|
||||
void about();
|
||||
@ -78,7 +74,7 @@ private:
|
||||
void createMenu();
|
||||
QAbstractItemModel *modelFromFile(const QString& fileName);
|
||||
|
||||
QCompleter *completer;
|
||||
QCompleter *completer = nullptr;
|
||||
TextEdit *completingTextEdit;
|
||||
};
|
||||
//! [0]
|
||||
|
@ -60,7 +60,7 @@
|
||||
|
||||
//! [0]
|
||||
TextEdit::TextEdit(QWidget *parent)
|
||||
: QTextEdit(parent), c(0)
|
||||
: QTextEdit(parent)
|
||||
{
|
||||
setPlainText(tr("This TextEdit provides autocompletions for words that have more than"
|
||||
" 3 characters. You can trigger autocompletion using ") +
|
||||
@ -78,7 +78,7 @@ TextEdit::~TextEdit()
|
||||
void TextEdit::setCompleter(QCompleter *completer)
|
||||
{
|
||||
if (c)
|
||||
QObject::disconnect(c, 0, this, 0);
|
||||
c->disconnect(this);
|
||||
|
||||
c = completer;
|
||||
|
||||
@ -101,7 +101,7 @@ QCompleter *TextEdit::completer() const
|
||||
//! [3]
|
||||
|
||||
//! [4]
|
||||
void TextEdit::insertCompletion(const QString& completion)
|
||||
void TextEdit::insertCompletion(const QString &completion)
|
||||
{
|
||||
if (c->widget() != this)
|
||||
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
|
||||
QTextEdit::keyPressEvent(e);
|
||||
//! [7]
|
||||
|
||||
//! [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()))
|
||||
return;
|
||||
|
||||
static QString eow("~!@#$%^&*()_+{}|:\"<>?,./;'[]\\-="); // end of word
|
||||
bool hasModifier = (e->modifiers() != Qt::NoModifier) && !ctrlOrShift;
|
||||
const bool hasModifier = (e->modifiers() != Qt::NoModifier) && !ctrlOrShift;
|
||||
QString completionPrefix = textUnderCursor();
|
||||
|
||||
if (!isShortcut && (hasModifier || e->text().isEmpty()|| completionPrefix.length() < 3
|
||||
|
@ -63,7 +63,7 @@ class TextEdit : public QTextEdit
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TextEdit(QWidget *parent = 0);
|
||||
TextEdit(QWidget *parent = nullptr);
|
||||
~TextEdit();
|
||||
|
||||
void setCompleter(QCompleter *c);
|
||||
@ -80,7 +80,7 @@ private:
|
||||
QString textUnderCursor() const;
|
||||
|
||||
private:
|
||||
QCompleter *c;
|
||||
QCompleter *c = nullptr;
|
||||
};
|
||||
//! [0]
|
||||
|
||||
|
@ -51,13 +51,14 @@
|
||||
#ifndef ECHOINTERFACE_H
|
||||
#define ECHOINTERFACE_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
//! [0]
|
||||
class EchoInterface
|
||||
{
|
||||
public:
|
||||
virtual ~EchoInterface() {}
|
||||
virtual ~EchoInterface() = default;
|
||||
virtual QString echo(const QString &message) = 0;
|
||||
};
|
||||
|
||||
|
@ -48,10 +48,17 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
#include "echowindow.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDir>
|
||||
#include <QLabel>
|
||||
#include <QLayout>
|
||||
#include <QLineEdit>
|
||||
#include <QMessageBox>
|
||||
#include <QPluginLoader>
|
||||
#include <QPushButton>
|
||||
|
||||
//! [0]
|
||||
EchoWindow::EchoWindow()
|
||||
{
|
||||
@ -101,7 +108,7 @@ void EchoWindow::createGUI()
|
||||
//! [3]
|
||||
bool EchoWindow::loadPlugin()
|
||||
{
|
||||
QDir pluginsDir(qApp->applicationDirPath());
|
||||
QDir pluginsDir(QCoreApplication::applicationDirPath());
|
||||
#if defined(Q_OS_WIN)
|
||||
if (pluginsDir.dirName().toLower() == "debug" || pluginsDir.dirName().toLower() == "release")
|
||||
pluginsDir.cdUp();
|
||||
@ -121,6 +128,7 @@ bool EchoWindow::loadPlugin()
|
||||
echoInterface = qobject_cast<EchoInterface *>(plugin);
|
||||
if (echoInterface)
|
||||
return true;
|
||||
pluginLoader.unload();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtWidgets>
|
||||
#include <QApplication>
|
||||
|
||||
#include "echowindow.h"
|
||||
#include "echointerface.h"
|
||||
|
@ -48,8 +48,6 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
#include "echoplugin.h"
|
||||
|
||||
//! [0]
|
||||
|
@ -48,34 +48,39 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
#include "languagechooser.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)
|
||||
{
|
||||
groupBox = new QGroupBox("Languages");
|
||||
|
||||
QGridLayout *groupBoxLayout = new QGridLayout;
|
||||
|
||||
QStringList qmFiles = findQmFiles();
|
||||
const QStringList qmFiles = findQmFiles();
|
||||
for (int i = 0; i < qmFiles.size(); ++i) {
|
||||
QCheckBox *checkBox = new QCheckBox(languageName(qmFiles[i]));
|
||||
qmFileForCheckBoxMap.insert(checkBox, qmFiles[i]);
|
||||
connect(checkBox,
|
||||
QOverload<bool>::of(&QCheckBox::toggled),
|
||||
this,
|
||||
&LanguageChooser::checkBoxToggled);
|
||||
if (languageMatch(defaultLang, qmFiles[i]))
|
||||
checkBox->setCheckState(Qt::Checked);
|
||||
const QString &qmlFile = qmFiles.at(i);
|
||||
QCheckBox *checkBox = new QCheckBox(languageName(qmlFile));
|
||||
qmFileForCheckBoxMap.insert(checkBox, qmlFile);
|
||||
connect(checkBox, &QCheckBox::toggled,
|
||||
this, &LanguageChooser::checkBoxToggled);
|
||||
if (languageMatch(defaultLang, qmlFile))
|
||||
checkBox->setCheckState(Qt::Checked);
|
||||
groupBoxLayout->addWidget(checkBox, i / 2, i % 2);
|
||||
}
|
||||
groupBox->setLayout(groupBoxLayout);
|
||||
|
||||
buttonBox = new QDialogButtonBox;
|
||||
|
||||
showAllButton = buttonBox->addButton("Show All",
|
||||
QDialogButtonBox::ActionRole);
|
||||
hideAllButton = buttonBox->addButton("Hide All",
|
||||
@ -92,7 +97,7 @@ LanguageChooser::LanguageChooser(const QString& defaultLang, QWidget *parent)
|
||||
setWindowTitle("I18N");
|
||||
}
|
||||
|
||||
bool LanguageChooser::languageMatch(const QString& lang, const QString& qmFile)
|
||||
bool LanguageChooser::languageMatch(const QString &lang, const QString &qmFile)
|
||||
{
|
||||
//qmFile: i18n_xx.qm
|
||||
const QString prefix = "i18n_";
|
||||
@ -110,21 +115,21 @@ bool LanguageChooser::eventFilter(QObject *object, QEvent *event)
|
||||
checkBox->setChecked(false);
|
||||
}
|
||||
}
|
||||
return QWidget::eventFilter(object, event);
|
||||
return QDialog::eventFilter(object, event);
|
||||
}
|
||||
|
||||
void LanguageChooser::closeEvent(QCloseEvent * /* event */)
|
||||
{
|
||||
qApp->quit();
|
||||
QCoreApplication::quit();
|
||||
}
|
||||
|
||||
void LanguageChooser::checkBoxToggled()
|
||||
{
|
||||
QCheckBox *checkBox = qobject_cast<QCheckBox *>(sender());
|
||||
MainWindow *window = mainWindowForCheckBoxMap[checkBox];
|
||||
MainWindow *window = mainWindowForCheckBoxMap.value(checkBox);
|
||||
if (!window) {
|
||||
QTranslator translator;
|
||||
translator.load(qmFileForCheckBoxMap[checkBox]);
|
||||
translator.load(qmFileForCheckBoxMap.value(checkBox));
|
||||
qApp->installTranslator(&translator);
|
||||
|
||||
window = new MainWindow;
|
||||
|
@ -52,7 +52,7 @@
|
||||
#define LANGUAGECHOOSER_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QMap>
|
||||
#include <QHash>
|
||||
#include <QStringList>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
@ -68,7 +68,7 @@ class LanguageChooser : public QDialog
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit LanguageChooser(const QString& defaultLang = QString(), QWidget *parent = 0);
|
||||
explicit LanguageChooser(const QString &defaultLang = QString(), QWidget *parent = nullptr);
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *object, QEvent *event) override;
|
||||
@ -80,17 +80,17 @@ private slots:
|
||||
void hideAll();
|
||||
|
||||
private:
|
||||
QStringList findQmFiles();
|
||||
QString languageName(const QString &qmFile);
|
||||
QColor colorForLanguage(const QString &language);
|
||||
static bool languageMatch(const QString& lang, const QString& qmFile);
|
||||
static QStringList findQmFiles();
|
||||
static QString languageName(const QString &qmFile);
|
||||
static QColor colorForLanguage(const QString &language);
|
||||
static bool languageMatch(const QString &lang, const QString &qmFile);
|
||||
|
||||
QGroupBox *groupBox;
|
||||
QDialogButtonBox *buttonBox;
|
||||
QAbstractButton *showAllButton;
|
||||
QAbstractButton *hideAllButton;
|
||||
QMap<QCheckBox *, QString> qmFileForCheckBoxMap;
|
||||
QMap<QCheckBox *, MainWindow *> mainWindowForCheckBoxMap;
|
||||
QHash<QCheckBox *, QString> qmFileForCheckBoxMap;
|
||||
QHash<QCheckBox *, MainWindow *> mainWindowForCheckBoxMap;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -48,18 +48,26 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
#include "mainwindow.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QCoreApplication>
|
||||
#include <QGroupBox>
|
||||
#include <QListWidget>
|
||||
#include <QMenuBar>
|
||||
#include <QRadioButton>
|
||||
#include <QStatusBar>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
static const char * const listEntries[] = {
|
||||
QT_TRANSLATE_NOOP("MainWindow", "First"),
|
||||
QT_TRANSLATE_NOOP("MainWindow", "Second"),
|
||||
QT_TRANSLATE_NOOP("MainWindow", "Third"),
|
||||
0
|
||||
nullptr
|
||||
};
|
||||
|
||||
MainWindow::MainWindow()
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
{
|
||||
centralWidget = new QWidget;
|
||||
setCentralWidget(centralWidget);
|
||||
@ -67,8 +75,8 @@ MainWindow::MainWindow()
|
||||
createGroupBox();
|
||||
|
||||
listWidget = new QListWidget;
|
||||
for (int i = 0; listEntries[i]; ++i)
|
||||
listWidget->addItem(tr(listEntries[i]));
|
||||
for (const char *entry : listEntries)
|
||||
listWidget->addItem(tr(entry));
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addWidget(groupBox);
|
||||
@ -76,7 +84,7 @@ MainWindow::MainWindow()
|
||||
centralWidget->setLayout(mainLayout);
|
||||
|
||||
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->setPalette(QPalette(Qt::red));
|
||||
|
@ -67,7 +67,7 @@ class MainWindow : public QMainWindow
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MainWindow();
|
||||
MainWindow(QWidget *parent = nullptr);
|
||||
|
||||
private:
|
||||
void createGroupBox();
|
||||
|
@ -49,8 +49,8 @@
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include "interfaces.h"
|
||||
#include "mainwindow.h"
|
||||
#include "interfaces.h"
|
||||
#include "paintarea.h"
|
||||
#include "plugindialog.h"
|
||||
|
||||
@ -67,9 +67,8 @@
|
||||
#include <QScrollArea>
|
||||
#include <QTimer>
|
||||
|
||||
MainWindow::MainWindow() :
|
||||
paintArea(new PaintArea),
|
||||
scrollArea(new QScrollArea)
|
||||
MainWindow::MainWindow() : paintArea(new PaintArea)
|
||||
, scrollArea(new QScrollArea)
|
||||
{
|
||||
scrollArea->setBackgroundRole(QPalette::Dark);
|
||||
scrollArea->setWidget(paintArea);
|
||||
@ -136,7 +135,11 @@ void MainWindow::brushWidth()
|
||||
void MainWindow::changeBrush()
|
||||
{
|
||||
auto action = qobject_cast<QAction *>(sender());
|
||||
if (!action)
|
||||
return;
|
||||
auto iBrush = qobject_cast<BrushInterface *>(action->parent());
|
||||
if (!iBrush)
|
||||
return;
|
||||
const QString brush = action->text();
|
||||
|
||||
paintArea->setBrush(iBrush, brush);
|
||||
@ -147,7 +150,11 @@ void MainWindow::changeBrush()
|
||||
void MainWindow::insertShape()
|
||||
{
|
||||
auto action = qobject_cast<QAction *>(sender());
|
||||
if (!action)
|
||||
return;
|
||||
auto iShape = qobject_cast<ShapeInterface *>(action->parent());
|
||||
if (!iShape)
|
||||
return;
|
||||
|
||||
const QPainterPath path = iShape->generateShape(action->text(), this);
|
||||
if (!path.isEmpty())
|
||||
@ -159,7 +166,11 @@ void MainWindow::insertShape()
|
||||
void MainWindow::applyFilter()
|
||||
{
|
||||
auto action = qobject_cast<QAction *>(sender());
|
||||
if (!action)
|
||||
return;
|
||||
auto iFilter = qobject_cast<FilterInterface *>(action->parent());
|
||||
if (!iFilter)
|
||||
return;
|
||||
|
||||
const QImage image = iFilter->filterImage(action->text(), paintArea->image(),
|
||||
this);
|
||||
@ -247,7 +258,7 @@ void MainWindow::loadPlugins()
|
||||
populateMenus(plugin);
|
||||
//! [4] //! [5]
|
||||
|
||||
pluginsDir = QDir(qApp->applicationDirPath());
|
||||
pluginsDir = QDir(QCoreApplication::applicationDirPath());
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
if (pluginsDir.dirName().toLower() == "debug" || pluginsDir.dirName().toLower() == "release")
|
||||
|
@ -49,14 +49,13 @@
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include "interfaces.h"
|
||||
#include "paintarea.h"
|
||||
#include "interfaces.h"
|
||||
|
||||
#include <QMouseEvent>
|
||||
#include <QPainter>
|
||||
|
||||
PaintArea::PaintArea(QWidget *parent) :
|
||||
QWidget(parent)
|
||||
PaintArea::PaintArea(QWidget *parent) : QWidget(parent)
|
||||
{
|
||||
setAttribute(Qt::WA_StaticContents);
|
||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||
|
@ -49,8 +49,8 @@
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include "interfaces.h"
|
||||
#include "plugindialog.h"
|
||||
#include "interfaces.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QGridLayout>
|
||||
|
@ -50,10 +50,10 @@
|
||||
|
||||
#include "basictoolsplugin.h"
|
||||
|
||||
#include <QInputDialog>
|
||||
#include <QPainter>
|
||||
#include <QRandomGenerator>
|
||||
#include <QtMath>
|
||||
#include <QtWidgets>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
//! [0]
|
||||
QStringList BasicToolsPlugin::brushes() const
|
||||
|
@ -54,12 +54,12 @@
|
||||
//! [0]
|
||||
#include <interfaces.h>
|
||||
|
||||
#include <QRect>
|
||||
#include <QObject>
|
||||
#include <QtPlugin>
|
||||
#include <QStringList>
|
||||
#include <QPainterPath>
|
||||
#include <QImage>
|
||||
#include <QObject>
|
||||
#include <QPainterPath>
|
||||
#include <QRect>
|
||||
#include <QStringList>
|
||||
#include <QtPlugin>
|
||||
|
||||
//! [1]
|
||||
class BasicToolsPlugin : public QObject,
|
||||
|
@ -50,10 +50,7 @@
|
||||
|
||||
#include "extrafiltersplugin.h"
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <QInputDialog>
|
||||
|
||||
QStringList ExtraFiltersPlugin::filters() const
|
||||
{
|
||||
|
@ -65,7 +65,7 @@ class RegExpDialog : public QDialog
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
RegExpDialog(QWidget *parent = 0);
|
||||
RegExpDialog(QWidget *parent = nullptr);
|
||||
|
||||
private slots:
|
||||
void refresh();
|
||||
|
@ -70,7 +70,7 @@ class RegularExpressionDialog : public QDialog
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
RegularExpressionDialog(QWidget *parent = 0);
|
||||
RegularExpressionDialog(QWidget *parent = nullptr);
|
||||
|
||||
private:
|
||||
void refresh();
|
||||
|
@ -48,10 +48,20 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
#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)
|
||||
: QDialog(parent)
|
||||
{
|
||||
@ -91,8 +101,7 @@ LocationDialog::LocationDialog(QWidget *parent)
|
||||
|
||||
locationsGroupBox = new QGroupBox(tr("Setting Locations"));
|
||||
|
||||
QStringList labels;
|
||||
labels << tr("Location") << tr("Access");
|
||||
const QStringList labels{tr("Location"), tr("Access")};
|
||||
|
||||
locationsTable = new QTableWidget;
|
||||
locationsTable->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
|
@ -68,7 +68,7 @@ class LocationDialog : public QDialog
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
LocationDialog(QWidget *parent = 0);
|
||||
LocationDialog(QWidget *parent = nullptr);
|
||||
|
||||
QSettings::Format format() const;
|
||||
QSettings::Scope scope() const;
|
||||
|
@ -48,15 +48,23 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
#include "locationdialog.h"
|
||||
#include "mainwindow.h"
|
||||
#include "settingstree.h"
|
||||
|
||||
MainWindow::MainWindow()
|
||||
: settingsTree(new SettingsTree)
|
||||
, locationDialog(nullptr)
|
||||
#include <QAction>
|
||||
#include <QApplication>
|
||||
#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);
|
||||
|
||||
|
@ -68,7 +68,7 @@ class MainWindow : public QMainWindow
|
||||
public:
|
||||
typedef QSharedPointer<QSettings> SettingsPtr;
|
||||
|
||||
MainWindow();
|
||||
MainWindow(QWidget *parent = nullptr);
|
||||
|
||||
private slots:
|
||||
void openSettings();
|
||||
@ -81,11 +81,11 @@ private:
|
||||
void createActions();
|
||||
void setSettingsObject(const SettingsPtr &settings);
|
||||
|
||||
SettingsTree *settingsTree;
|
||||
LocationDialog *locationDialog;
|
||||
QAction *refreshAct;
|
||||
QAction *autoRefreshAct;
|
||||
QAction *fallbacksAct;
|
||||
SettingsTree *settingsTree = nullptr;
|
||||
LocationDialog *locationDialog = nullptr;
|
||||
QAction *refreshAct = nullptr;
|
||||
QAction *autoRefreshAct = nullptr;
|
||||
QAction *fallbacksAct = nullptr;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -48,20 +48,20 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
#include "settingstree.h"
|
||||
#include "variantdelegate.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDesktopWidget>
|
||||
#include <QHeaderView>
|
||||
#include <QSettings>
|
||||
|
||||
SettingsTree::SettingsTree(QWidget *parent)
|
||||
: QTreeWidget(parent)
|
||||
, autoRefresh(false)
|
||||
{
|
||||
setItemDelegate(new VariantDelegate(this));
|
||||
|
||||
QStringList labels;
|
||||
labels << tr("Setting") << tr("Type") << tr("Value");
|
||||
setHeaderLabels(labels);
|
||||
setHeaderLabels({tr("Setting"), tr("Type"), tr("Value")});
|
||||
header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
|
||||
header()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
|
||||
header()->setSectionResizeMode(2, QHeaderView::Stretch);
|
||||
@ -77,10 +77,6 @@ SettingsTree::SettingsTree(QWidget *parent)
|
||||
connect(&refreshTimer, &QTimer::timeout, this, &SettingsTree::maybeRefresh);
|
||||
}
|
||||
|
||||
SettingsTree::~SettingsTree()
|
||||
{
|
||||
}
|
||||
|
||||
void SettingsTree::setSettingsObject(const SettingsPtr &newSettings)
|
||||
{
|
||||
settings = newSettings;
|
||||
@ -137,7 +133,7 @@ void SettingsTree::refresh()
|
||||
this, &SettingsTree::updateSetting);
|
||||
|
||||
settings->sync();
|
||||
updateChildItems(0);
|
||||
updateChildItems(nullptr);
|
||||
|
||||
connect(this, &QTreeWidget::itemChanged,
|
||||
this, &SettingsTree::updateSetting);
|
||||
@ -228,7 +224,7 @@ void SettingsTree::updateChildItems(QTreeWidgetItem *parent)
|
||||
QTreeWidgetItem *SettingsTree::createItem(const QString &text,
|
||||
QTreeWidgetItem *parent, int index)
|
||||
{
|
||||
QTreeWidgetItem *after = 0;
|
||||
QTreeWidgetItem *after = nullptr;
|
||||
if (index != 0)
|
||||
after = childAt(parent, index - 1);
|
||||
|
||||
@ -243,24 +239,18 @@ QTreeWidgetItem *SettingsTree::createItem(const QString &text,
|
||||
return item;
|
||||
}
|
||||
|
||||
QTreeWidgetItem *SettingsTree::childAt(QTreeWidgetItem *parent, int index)
|
||||
QTreeWidgetItem *SettingsTree::childAt(QTreeWidgetItem *parent, int index) const
|
||||
{
|
||||
if (parent)
|
||||
return parent->child(index);
|
||||
else
|
||||
return topLevelItem(index);
|
||||
return (parent ? parent->child(index) : topLevelItem(index));
|
||||
}
|
||||
|
||||
int SettingsTree::childCount(QTreeWidgetItem *parent)
|
||||
int SettingsTree::childCount(QTreeWidgetItem *parent) const
|
||||
{
|
||||
if (parent)
|
||||
return parent->childCount();
|
||||
else
|
||||
return topLevelItemCount();
|
||||
return (parent ? parent->childCount() : topLevelItemCount());
|
||||
}
|
||||
|
||||
int SettingsTree::findChild(QTreeWidgetItem *parent, const QString &text,
|
||||
int startIndex)
|
||||
int startIndex) const
|
||||
{
|
||||
for (int i = startIndex; i < childCount(parent); ++i) {
|
||||
if (childAt(parent, i)->text(0) == text)
|
||||
|
@ -65,10 +65,9 @@ class SettingsTree : public QTreeWidget
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
typedef QSharedPointer<QSettings> SettingsPtr;
|
||||
using SettingsPtr = QSharedPointer<QSettings>;
|
||||
|
||||
SettingsTree(QWidget *parent = 0);
|
||||
~SettingsTree();
|
||||
SettingsTree(QWidget *parent = nullptr);
|
||||
|
||||
void setSettingsObject(const SettingsPtr &settings);
|
||||
QSize sizeHint() const override;
|
||||
@ -89,16 +88,16 @@ private:
|
||||
void updateChildItems(QTreeWidgetItem *parent);
|
||||
QTreeWidgetItem *createItem(const QString &text, QTreeWidgetItem *parent,
|
||||
int index);
|
||||
QTreeWidgetItem *childAt(QTreeWidgetItem *parent, int index);
|
||||
int childCount(QTreeWidgetItem *parent);
|
||||
int findChild(QTreeWidgetItem *parent, const QString &text, int startIndex);
|
||||
QTreeWidgetItem *childAt(QTreeWidgetItem *parent, int index) const;
|
||||
int childCount(QTreeWidgetItem *parent) const;
|
||||
int findChild(QTreeWidgetItem *parent, const QString &text, int startIndex) const;
|
||||
void moveItemForward(QTreeWidgetItem *parent, int oldIndex, int newIndex);
|
||||
|
||||
SettingsPtr settings;
|
||||
QTimer refreshTimer;
|
||||
bool autoRefresh;
|
||||
QIcon groupIcon;
|
||||
QIcon keyIcon;
|
||||
bool autoRefresh = false;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -48,12 +48,14 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
#include "variantdelegate.h"
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QLineEdit>
|
||||
#include <QRegularExpressionValidator>
|
||||
|
||||
VariantDelegate::VariantDelegate(QObject *parent)
|
||||
: QItemDelegate(parent)
|
||||
: QStyledItemDelegate(parent)
|
||||
{
|
||||
boolExp.setPattern("true|false");
|
||||
boolExp.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
|
||||
@ -82,12 +84,12 @@ void VariantDelegate::paint(QPainter *painter,
|
||||
if (!isSupportedType(value.type())) {
|
||||
QStyleOptionViewItem myOption = option;
|
||||
myOption.state &= ~QStyle::State_Enabled;
|
||||
QItemDelegate::paint(painter, myOption, index);
|
||||
QStyledItemDelegate::paint(painter, myOption, index);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QItemDelegate::paint(painter, option, index);
|
||||
QStyledItemDelegate::paint(painter, option, index);
|
||||
}
|
||||
|
||||
QWidget *VariantDelegate::createEditor(QWidget *parent,
|
||||
@ -95,11 +97,11 @@ QWidget *VariantDelegate::createEditor(QWidget *parent,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
if (index.column() != 2)
|
||||
return 0;
|
||||
return nullptr;
|
||||
|
||||
QVariant originalValue = index.model()->data(index, Qt::UserRole);
|
||||
if (!isSupportedType(originalValue.type()))
|
||||
return 0;
|
||||
return nullptr;
|
||||
|
||||
QLineEdit *lineEdit = new QLineEdit(parent);
|
||||
lineEdit->setFrame(false);
|
||||
@ -149,7 +151,7 @@ QWidget *VariantDelegate::createEditor(QWidget *parent,
|
||||
regExp = unsignedIntegerExp;
|
||||
break;
|
||||
default:
|
||||
;
|
||||
break;
|
||||
}
|
||||
|
||||
if (regExp.isValid()) {
|
||||
|
@ -51,15 +51,15 @@
|
||||
#ifndef VARIANTDELEGATE_H
|
||||
#define VARIANTDELEGATE_H
|
||||
|
||||
#include <QItemDelegate>
|
||||
#include <QStyledItemDelegate>
|
||||
#include <QRegularExpression>
|
||||
|
||||
class VariantDelegate : public QItemDelegate
|
||||
class VariantDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
VariantDelegate(QObject *parent = 0);
|
||||
VariantDelegate(QObject *parent = nullptr);
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const override;
|
||||
|
@ -48,8 +48,6 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
#include "simplestyle.h"
|
||||
|
||||
void SimpleStyle::polish(QPalette &palette)
|
||||
|
@ -53,16 +53,12 @@
|
||||
|
||||
#include <QProxyStyle>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QPalette;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class SimpleStyle : public QProxyStyle
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SimpleStyle() {};
|
||||
SimpleStyle() = default;
|
||||
|
||||
void polish(QPalette &palette) override;
|
||||
};
|
||||
|
@ -48,15 +48,13 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
#include "simplestyleplugin.h"
|
||||
#include "simplestyle.h"
|
||||
|
||||
//! [0]
|
||||
QStringList SimpleStylePlugin::keys() const
|
||||
{
|
||||
return QStringList() << "SimpleStyle";
|
||||
return {"SimpleStyle"};
|
||||
}
|
||||
//! [0]
|
||||
|
||||
@ -65,6 +63,6 @@ QStyle *SimpleStylePlugin::create(const QString &key)
|
||||
{
|
||||
if (key.toLower() == "simplestyle")
|
||||
return new SimpleStyle;
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
//! [1]
|
||||
|
@ -53,11 +53,6 @@
|
||||
|
||||
#include <QStylePlugin>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QStringList;
|
||||
class QStyle;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
//! [0]
|
||||
class SimpleStylePlugin : public QStylePlugin
|
||||
{
|
||||
@ -65,7 +60,7 @@ class SimpleStylePlugin : public QStylePlugin
|
||||
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QStyleFactoryInterface" FILE "simplestyle.json")
|
||||
|
||||
public:
|
||||
SimpleStylePlugin() {}
|
||||
SimpleStylePlugin() = default;
|
||||
|
||||
QStringList keys() const;
|
||||
QStyle *create(const QString &key) override;
|
||||
|
@ -48,7 +48,8 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtWidgets>
|
||||
#include <QApplication>
|
||||
#include <QStyleFactory>
|
||||
|
||||
#include "stylewindow.h"
|
||||
|
||||
|
@ -48,7 +48,9 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtWidgets>
|
||||
#include <QGridLayout>
|
||||
#include <QGroupBox>
|
||||
#include <QPushButton>
|
||||
|
||||
#include "stylewindow.h"
|
||||
|
||||
|
@ -48,13 +48,28 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtWidgets>
|
||||
#include "treemodelcompleter.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]
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
: QMainWindow(parent), completer(0), lineEdit(0)
|
||||
: QMainWindow(parent)
|
||||
{
|
||||
createMenu();
|
||||
|
||||
@ -151,10 +166,10 @@ void MainWindow::createMenu()
|
||||
connect(aboutAct, &QAction::triggered, this, &MainWindow::about);
|
||||
connect(aboutQtAct, &QAction::triggered, qApp, &QApplication::aboutQt);
|
||||
|
||||
QMenu* fileMenu = menuBar()->addMenu(tr("File"));
|
||||
QMenu *fileMenu = menuBar()->addMenu(tr("File"));
|
||||
fileMenu->addAction(exitAction);
|
||||
|
||||
QMenu* helpMenu = menuBar()->addMenu(tr("About"));
|
||||
QMenu *helpMenu = menuBar()->addMenu(tr("About"));
|
||||
helpMenu->addAction(aboutAct);
|
||||
helpMenu->addAction(aboutQtAct);
|
||||
}
|
||||
@ -175,7 +190,7 @@ void MainWindow::changeMode(int index)
|
||||
}
|
||||
//! [5]
|
||||
|
||||
QAbstractItemModel *MainWindow::modelFromFile(const QString& fileName)
|
||||
QAbstractItemModel *MainWindow::modelFromFile(const QString &fileName)
|
||||
{
|
||||
QFile file(fileName);
|
||||
if (!file.open(QFile::ReadOnly))
|
||||
@ -184,39 +199,35 @@ QAbstractItemModel *MainWindow::modelFromFile(const QString& fileName)
|
||||
#ifndef QT_NO_CURSOR
|
||||
QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
|
||||
#endif
|
||||
QStringList words;
|
||||
|
||||
QStandardItemModel *model = new QStandardItemModel(completer);
|
||||
QVector<QStandardItem *> parents(10);
|
||||
parents[0] = model->invisibleRootItem();
|
||||
|
||||
QRegularExpression re("^\\s+");
|
||||
while (!file.atEnd()) {
|
||||
QString line = file.readLine();
|
||||
QString trimmedLine = line.trimmed();
|
||||
if (line.isEmpty() || trimmedLine.isEmpty())
|
||||
const QString line = QString::fromUtf8(file.readLine()).trimmed();
|
||||
const QString trimmedLine = line.trimmed();
|
||||
if (trimmedLine.isEmpty())
|
||||
continue;
|
||||
|
||||
QRegularExpression re("^\\s+");
|
||||
QRegularExpressionMatch match = re.match(line);
|
||||
const QRegularExpressionMatch match = re.match(line);
|
||||
int nonws = match.capturedStart();
|
||||
int level = 0;
|
||||
if (nonws == -1) {
|
||||
level = 0;
|
||||
} else {
|
||||
if (line.startsWith("\t")) {
|
||||
level = match.capturedLength();
|
||||
} else {
|
||||
level = match.capturedLength()/4;
|
||||
}
|
||||
const int capLen = match.capturedLength();
|
||||
level = line.startsWith(QLatin1Char('\t')) ? capLen / 4 : capLen;
|
||||
}
|
||||
|
||||
if (level+1 >= parents.size())
|
||||
parents.resize(parents.size()*2);
|
||||
if (level + 1 >= parents.size())
|
||||
parents.resize(parents.size() * 2);
|
||||
|
||||
QStandardItem *item = new QStandardItem;
|
||||
item->setText(trimmedLine);
|
||||
parents[level]->appendRow(item);
|
||||
parents[level+1] = item;
|
||||
parents[level + 1] = item;
|
||||
}
|
||||
|
||||
#ifndef QT_NO_CURSOR
|
||||
@ -252,7 +263,7 @@ void MainWindow::changeCase(int cs)
|
||||
}
|
||||
//! [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));
|
||||
}
|
||||
|
@ -60,8 +60,6 @@ class QAbstractItemModel;
|
||||
class QComboBox;
|
||||
class QLabel;
|
||||
class QLineEdit;
|
||||
class QProgressBar;
|
||||
class QCheckBox;
|
||||
class QTreeView;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
@ -71,27 +69,27 @@ class MainWindow : public QMainWindow
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MainWindow(QWidget *parent = 0);
|
||||
MainWindow(QWidget *parent = nullptr);
|
||||
|
||||
private slots:
|
||||
void about();
|
||||
void changeCase(int);
|
||||
void changeMode(int);
|
||||
void highlight(const QModelIndex&);
|
||||
void updateContentsLabel(const QString&);
|
||||
void highlight(const QModelIndex &index);
|
||||
void updateContentsLabel(const QString &sep);
|
||||
//! [0]
|
||||
|
||||
//! [1]
|
||||
private:
|
||||
void createMenu();
|
||||
QAbstractItemModel *modelFromFile(const QString& fileName);
|
||||
QAbstractItemModel *modelFromFile(const QString &fileName);
|
||||
|
||||
QTreeView *treeView;
|
||||
QComboBox *caseCombo;
|
||||
QComboBox *modeCombo;
|
||||
QLabel *contentsLabel;
|
||||
TreeModelCompleter *completer;
|
||||
QLineEdit *lineEdit;
|
||||
QTreeView *treeView = nullptr;
|
||||
QComboBox *caseCombo = nullptr;
|
||||
QComboBox *modeCombo = nullptr;
|
||||
QLabel *contentsLabel = nullptr;
|
||||
TreeModelCompleter *completer = nullptr;
|
||||
QLineEdit *lineEdit = nullptr;
|
||||
};
|
||||
//! [1]
|
||||
|
||||
|
@ -80,26 +80,20 @@ QString TreeModelCompleter::separator() const
|
||||
//! [3]
|
||||
QStringList TreeModelCompleter::splitPath(const QString &path) const
|
||||
{
|
||||
if (sep.isNull()) {
|
||||
return QCompleter::splitPath(path);
|
||||
}
|
||||
|
||||
return path.split(sep);
|
||||
return (sep.isNull() ? QCompleter::splitPath(path) : path.split(sep));
|
||||
}
|
||||
//! [3]
|
||||
|
||||
//! [4]
|
||||
QString TreeModelCompleter::pathFromIndex(const QModelIndex &index) const
|
||||
{
|
||||
if (sep.isNull()) {
|
||||
if (sep.isNull())
|
||||
return QCompleter::pathFromIndex(index);
|
||||
}
|
||||
|
||||
// navigate up and accumulate data
|
||||
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());
|
||||
}
|
||||
|
||||
return dataList.join(sep);
|
||||
}
|
||||
|
@ -60,8 +60,8 @@ class TreeModelCompleter : public QCompleter
|
||||
Q_PROPERTY(QString separator READ separator WRITE setSeparator)
|
||||
|
||||
public:
|
||||
explicit TreeModelCompleter(QObject *parent = 0);
|
||||
explicit TreeModelCompleter(QAbstractItemModel *model, QObject *parent = 0);
|
||||
explicit TreeModelCompleter(QObject *parent = nullptr);
|
||||
explicit TreeModelCompleter(QAbstractItemModel *model, QObject *parent = nullptr);
|
||||
|
||||
QString separator() const;
|
||||
public slots:
|
||||
|
@ -50,18 +50,16 @@
|
||||
|
||||
#include "commands.h"
|
||||
|
||||
static const int setShapeRectCommandId = 1;
|
||||
static const int setShapeColorCommandId = 2;
|
||||
static constexpr int setShapeRectCommandId = 1;
|
||||
static constexpr int setShapeColorCommandId = 2;
|
||||
|
||||
/******************************************************************************
|
||||
** AddShapeCommand
|
||||
*/
|
||||
|
||||
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()
|
||||
@ -81,13 +79,11 @@ void AddShapeCommand::redo()
|
||||
*/
|
||||
|
||||
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));
|
||||
m_doc = doc;
|
||||
m_shape = doc->shape(shapeName);
|
||||
m_shapeName = shapeName;
|
||||
}
|
||||
|
||||
void RemoveShapeCommand::undo()
|
||||
@ -105,15 +101,11 @@ void RemoveShapeCommand::redo()
|
||||
*/
|
||||
|
||||
SetShapeColorCommand::SetShapeColorCommand(Document *doc, const QString &shapeName,
|
||||
const QColor &color, QUndoCommand *parent)
|
||||
: QUndoCommand(parent)
|
||||
const QColor &color, 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));
|
||||
|
||||
m_doc = doc;
|
||||
m_shapeName = shapeName;
|
||||
m_oldColor = doc->shape(shapeName).color();
|
||||
m_newColor = color;
|
||||
}
|
||||
|
||||
void SetShapeColorCommand::undo()
|
||||
@ -149,15 +141,11 @@ int SetShapeColorCommand::id() const
|
||||
*/
|
||||
|
||||
SetShapeRectCommand::SetShapeRectCommand(Document *doc, const QString &shapeName,
|
||||
const QRect &rect, QUndoCommand *parent)
|
||||
: QUndoCommand(parent)
|
||||
const QRect &rect, 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));
|
||||
|
||||
m_doc = doc;
|
||||
m_shapeName = shapeName;
|
||||
m_oldRect = doc->shape(shapeName).rect();
|
||||
m_newRect = rect;
|
||||
}
|
||||
|
||||
void SetShapeRectCommand::undo()
|
||||
|
@ -57,7 +57,8 @@
|
||||
class AddShapeCommand : public QUndoCommand
|
||||
{
|
||||
public:
|
||||
AddShapeCommand(Document *doc, const Shape &shape, QUndoCommand *parent = 0);
|
||||
AddShapeCommand(Document *doc, const Shape &shape,
|
||||
QUndoCommand *parent = nullptr);
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
|
||||
@ -70,7 +71,8 @@ private:
|
||||
class RemoveShapeCommand : public QUndoCommand
|
||||
{
|
||||
public:
|
||||
RemoveShapeCommand(Document *doc, const QString &shapeName, QUndoCommand *parent = 0);
|
||||
RemoveShapeCommand(Document *doc, const QString &shapeName,
|
||||
QUndoCommand *parent = nullptr);
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
|
||||
@ -83,8 +85,8 @@ private:
|
||||
class SetShapeColorCommand : public QUndoCommand
|
||||
{
|
||||
public:
|
||||
SetShapeColorCommand(Document *doc, const QString &shapeName, const QColor &color,
|
||||
QUndoCommand *parent = 0);
|
||||
SetShapeColorCommand(Document *doc, const QString &shapeName,
|
||||
const QColor &color, QUndoCommand *parent = nullptr);
|
||||
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
@ -102,8 +104,8 @@ private:
|
||||
class SetShapeRectCommand : public QUndoCommand
|
||||
{
|
||||
public:
|
||||
SetShapeRectCommand(Document *doc, const QString &shapeName, const QRect &rect,
|
||||
QUndoCommand *parent = 0);
|
||||
SetShapeRectCommand(Document *doc, const QString &shapeName,
|
||||
const QRect &rect, QUndoCommand *parent = nullptr);
|
||||
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
|
@ -48,14 +48,15 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <qevent.h>
|
||||
#include <QPainter>
|
||||
#include <QTextStream>
|
||||
#include <QUndoStack>
|
||||
#include "document.h"
|
||||
#include "commands.h"
|
||||
|
||||
static const int resizeHandleWidth = 6;
|
||||
#include <QPainter>
|
||||
#include <QPaintEvent>
|
||||
#include <QTextStream>
|
||||
#include <QUndoStack>
|
||||
|
||||
static constexpr int resizeHandleWidth = 6;
|
||||
|
||||
/******************************************************************************
|
||||
** Shape
|
||||
@ -96,26 +97,21 @@ QRect Shape::resizeHandle() const
|
||||
|
||||
QString Shape::typeToString(Type type)
|
||||
{
|
||||
QString result;
|
||||
|
||||
switch (type) {
|
||||
case Rectangle:
|
||||
result = QLatin1String("Rectangle");
|
||||
break;
|
||||
return QLatin1String("Rectangle");
|
||||
case Circle:
|
||||
result = QLatin1String("Circle");
|
||||
break;
|
||||
return QLatin1String("Circle");
|
||||
case Triangle:
|
||||
result = QLatin1String("Triangle");
|
||||
break;
|
||||
return QLatin1String("Triangle");
|
||||
}
|
||||
|
||||
return result;
|
||||
return QString();
|
||||
}
|
||||
|
||||
Shape::Type Shape::stringToType(const QString &s, bool *ok)
|
||||
{
|
||||
if (ok != 0)
|
||||
if (ok != nullptr)
|
||||
*ok = true;
|
||||
|
||||
if (s == QLatin1String("Rectangle"))
|
||||
@ -125,7 +121,7 @@ Shape::Type Shape::stringToType(const QString &s, bool *ok)
|
||||
if (s == QLatin1String("Triangle"))
|
||||
return Triangle;
|
||||
|
||||
if (ok != 0)
|
||||
if (ok != nullptr)
|
||||
*ok = false;
|
||||
return Rectangle;
|
||||
}
|
||||
@ -135,10 +131,8 @@ Shape::Type Shape::stringToType(const QString &s, bool *ok)
|
||||
*/
|
||||
|
||||
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);
|
||||
setBackgroundRole(QPalette::Base);
|
||||
|
||||
|
@ -70,7 +70,7 @@ public:
|
||||
QColor color() const;
|
||||
|
||||
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;
|
||||
|
||||
@ -88,7 +88,7 @@ class Document : public QWidget
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Document(QWidget *parent = 0);
|
||||
Document(QWidget *parent = nullptr);
|
||||
|
||||
QString addShape(const Shape &shape);
|
||||
void deleteShape(const QString &shapeName);
|
||||
@ -121,14 +121,13 @@ private:
|
||||
int indexAt(const QPoint &pos) const;
|
||||
QString uniqueName(const QString &name) const;
|
||||
|
||||
QList<Shape> m_shapeList;
|
||||
int m_currentIndex;
|
||||
int m_mousePressIndex;
|
||||
QVector<Shape> m_shapeList;
|
||||
QPoint m_mousePressOffset;
|
||||
bool m_resizeHandlePressed;
|
||||
QString m_fileName;
|
||||
|
||||
QUndoStack *m_undoStack;
|
||||
QUndoStack *m_undoStack = nullptr;
|
||||
int m_currentIndex = -1;
|
||||
int m_mousePressIndex = -1;
|
||||
bool m_resizeHandlePressed = false;
|
||||
};
|
||||
|
||||
#endif // DOCUMENT_H
|
||||
|
@ -48,6 +48,10 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "mainwindow.h"
|
||||
#include "document.h"
|
||||
#include "commands.h"
|
||||
|
||||
#include <QUndoGroup>
|
||||
#include <QUndoStack>
|
||||
#include <QFileDialog>
|
||||
@ -55,9 +59,6 @@
|
||||
#include <QRandomGenerator>
|
||||
#include <QTextStream>
|
||||
#include <QToolButton>
|
||||
#include "document.h"
|
||||
#include "mainwindow.h"
|
||||
#include "commands.h"
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
@ -122,17 +123,17 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
void MainWindow::updateActions()
|
||||
{
|
||||
Document *doc = currentDocument();
|
||||
m_undoGroup->setActiveStack(doc == 0 ? 0 : doc->undoStack());
|
||||
QString shapeName = doc == 0 ? QString() : doc->currentShapeName();
|
||||
m_undoGroup->setActiveStack(doc == nullptr ? nullptr : doc->undoStack());
|
||||
QString shapeName = doc == nullptr ? QString() : doc->currentShapeName();
|
||||
|
||||
actionAddRobot->setEnabled(doc != 0);
|
||||
actionAddSnowman->setEnabled(doc != 0);
|
||||
actionAddCircle->setEnabled(doc != 0);
|
||||
actionAddRectangle->setEnabled(doc != 0);
|
||||
actionAddTriangle->setEnabled(doc != 0);
|
||||
actionClose->setEnabled(doc != 0);
|
||||
actionSave->setEnabled(doc != 0 && !doc->undoStack()->isClean());
|
||||
undoLimit->setEnabled(doc != 0 && doc->undoStack()->count() == 0);
|
||||
actionAddRobot->setEnabled(doc != nullptr);
|
||||
actionAddSnowman->setEnabled(doc != nullptr);
|
||||
actionAddCircle->setEnabled(doc != nullptr);
|
||||
actionAddRectangle->setEnabled(doc != nullptr);
|
||||
actionAddTriangle->setEnabled(doc != nullptr);
|
||||
actionClose->setEnabled(doc != nullptr);
|
||||
actionSave->setEnabled(doc != nullptr && !doc->undoStack()->isClean());
|
||||
undoLimit->setEnabled(doc != nullptr && doc->undoStack()->count() == 0);
|
||||
|
||||
if (shapeName.isEmpty()) {
|
||||
actionRed->setEnabled(false);
|
||||
@ -147,7 +148,7 @@ void MainWindow::updateActions()
|
||||
actionRemoveShape->setEnabled(true);
|
||||
}
|
||||
|
||||
if (doc != 0) {
|
||||
if (doc != nullptr) {
|
||||
int index = documentTabs->indexOf(doc);
|
||||
Q_ASSERT(index != -1);
|
||||
static const QIcon unsavedIcon(":/icons/filesave.png");
|
||||
@ -264,7 +265,7 @@ void MainWindow::removeDocument(Document *doc)
|
||||
void MainWindow::saveDocument()
|
||||
{
|
||||
Document *doc = currentDocument();
|
||||
if (doc == 0)
|
||||
if (doc == nullptr)
|
||||
return;
|
||||
|
||||
for (;;) {
|
||||
@ -298,7 +299,7 @@ void MainWindow::saveDocument()
|
||||
void MainWindow::closeDocument()
|
||||
{
|
||||
Document *doc = currentDocument();
|
||||
if (doc == 0)
|
||||
if (doc == nullptr)
|
||||
return;
|
||||
|
||||
if (!doc->undoStack()->isClean()) {
|
||||
@ -338,10 +339,10 @@ static QRect randomRect(const QSize &s)
|
||||
{
|
||||
QSize min = Shape::minSize;
|
||||
|
||||
int left = (int) ((0.0 + s.width() - min.width())*(QRandomGenerator::global()->bounded(1.0)));
|
||||
int top = (int) ((0.0 + 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 height = (int) ((0.0 + s.height() - top - min.height())*(QRandomGenerator::global()->bounded(1.0))) + min.height();
|
||||
int left = qRound((s.width() - min.width()) * (QRandomGenerator::global()->bounded(1.0)));
|
||||
int top = qRound((s.height() - min.height()) * (QRandomGenerator::global()->bounded(1.0)));
|
||||
int width = qRound((s.width() - left - min.width()) * (QRandomGenerator::global()->bounded(1.0))) + min.width();
|
||||
int height = qRound((s.height() - top - min.height()) * (QRandomGenerator::global()->bounded(1.0))) + min.height();
|
||||
|
||||
return QRect(left, top, width, height);
|
||||
}
|
||||
@ -349,7 +350,7 @@ static QRect randomRect(const QSize &s)
|
||||
void MainWindow::addShape()
|
||||
{
|
||||
Document *doc = currentDocument();
|
||||
if (doc == 0)
|
||||
if (doc == nullptr)
|
||||
return;
|
||||
|
||||
Shape::Type type;
|
||||
@ -369,7 +370,7 @@ void MainWindow::addShape()
|
||||
void MainWindow::removeShape()
|
||||
{
|
||||
Document *doc = currentDocument();
|
||||
if (doc == 0)
|
||||
if (doc == nullptr)
|
||||
return;
|
||||
|
||||
QString shapeName = doc->currentShapeName();
|
||||
@ -382,7 +383,7 @@ void MainWindow::removeShape()
|
||||
void MainWindow::setShapeColor()
|
||||
{
|
||||
Document *doc = currentDocument();
|
||||
if (doc == 0)
|
||||
if (doc == nullptr)
|
||||
return;
|
||||
|
||||
QString shapeName = doc->currentShapeName();
|
||||
@ -409,7 +410,7 @@ void MainWindow::setShapeColor()
|
||||
void MainWindow::addSnowman()
|
||||
{
|
||||
Document *doc = currentDocument();
|
||||
if (doc == 0)
|
||||
if (doc == nullptr)
|
||||
return;
|
||||
|
||||
// Create a macro command using beginMacro() and endMacro()
|
||||
@ -427,7 +428,7 @@ void MainWindow::addSnowman()
|
||||
void MainWindow::addRobot()
|
||||
{
|
||||
Document *doc = currentDocument();
|
||||
if (doc == 0)
|
||||
if (doc == nullptr)
|
||||
return;
|
||||
|
||||
// Compose a macro command by explicitly adding children to a parent command
|
||||
|
@ -61,7 +61,7 @@ class MainWindow : public QMainWindow, public Ui::MainWindow
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MainWindow(QWidget *parent = 0);
|
||||
MainWindow(QWidget *parent = nullptr);
|
||||
|
||||
void addDocument(Document *doc);
|
||||
void removeDocument(Document *doc);
|
||||
|
@ -48,19 +48,17 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
#include "commands.h"
|
||||
#include "diagramitem.h"
|
||||
|
||||
#include <QGraphicsScene>
|
||||
|
||||
//! [0]
|
||||
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]
|
||||
|
||||
@ -71,7 +69,7 @@ bool MoveCommand::mergeWith(const QUndoCommand *command)
|
||||
DiagramItem *item = moveCommand->myDiagramItem;
|
||||
|
||||
if (myDiagramItem != item)
|
||||
return false;
|
||||
return false;
|
||||
|
||||
newPos = item->pos();
|
||||
setText(QObject::tr("Move %1")
|
||||
@ -102,9 +100,8 @@ void MoveCommand::redo()
|
||||
|
||||
//! [4]
|
||||
DeleteCommand::DeleteCommand(QGraphicsScene *scene, QUndoCommand *parent)
|
||||
: QUndoCommand(parent)
|
||||
: QUndoCommand(parent), myGraphicsScene(scene)
|
||||
{
|
||||
myGraphicsScene = scene;
|
||||
QList<QGraphicsItem *> list = myGraphicsScene->selectedItems();
|
||||
list.first()->setSelected(false);
|
||||
myDiagramItem = static_cast<DiagramItem *>(list.first());
|
||||
@ -131,11 +128,10 @@ void DeleteCommand::redo()
|
||||
//! [7]
|
||||
AddCommand::AddCommand(DiagramItem::DiagramType addType,
|
||||
QGraphicsScene *scene, QUndoCommand *parent)
|
||||
: QUndoCommand(parent)
|
||||
: QUndoCommand(parent), myGraphicsScene(scene)
|
||||
{
|
||||
static int itemCount = 0;
|
||||
|
||||
myGraphicsScene = scene;
|
||||
myDiagramItem = new DiagramItem(addType);
|
||||
initialPosition = QPointF((itemCount * 15) % int(scene->width()),
|
||||
(itemCount * 15) % int(scene->height()));
|
||||
|
@ -62,7 +62,7 @@ public:
|
||||
enum { Id = 1234 };
|
||||
|
||||
MoveCommand(DiagramItem *diagramItem, const QPointF &oldPos,
|
||||
QUndoCommand *parent = 0);
|
||||
QUndoCommand *parent = nullptr);
|
||||
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
@ -80,7 +80,7 @@ private:
|
||||
class DeleteCommand : public QUndoCommand
|
||||
{
|
||||
public:
|
||||
explicit DeleteCommand(QGraphicsScene *graphicsScene, QUndoCommand *parent = 0);
|
||||
explicit DeleteCommand(QGraphicsScene *graphicsScene, QUndoCommand *parent = nullptr);
|
||||
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
@ -96,7 +96,7 @@ class AddCommand : public QUndoCommand
|
||||
{
|
||||
public:
|
||||
AddCommand(DiagramItem::DiagramType addType, QGraphicsScene *graphicsScene,
|
||||
QUndoCommand *parent = 0);
|
||||
QUndoCommand *parent = nullptr);
|
||||
~AddCommand();
|
||||
|
||||
void undo() override;
|
||||
|
@ -48,10 +48,11 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
#include "diagramitem.h"
|
||||
|
||||
#include <QBrush>
|
||||
#include <QRandomGenerator>
|
||||
|
||||
DiagramItem::DiagramItem(DiagramType diagramType, QGraphicsItem *item)
|
||||
: QGraphicsPolygonItem(item)
|
||||
{
|
||||
@ -65,7 +66,9 @@ DiagramItem::DiagramItem(DiagramType diagramType, QGraphicsItem *item)
|
||||
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);
|
||||
setBrush(brush);
|
||||
setFlag(QGraphicsItem::ItemIsSelectable);
|
||||
|
@ -66,9 +66,10 @@ public:
|
||||
enum { Type = UserType + 1 };
|
||||
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;
|
||||
}
|
||||
int type() const override { return Type; }
|
||||
|
@ -48,27 +48,24 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
#include "diagramscene.h"
|
||||
#include "diagramitem.h"
|
||||
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
|
||||
DiagramScene::DiagramScene(QObject *parent)
|
||||
: QGraphicsScene(parent)
|
||||
{
|
||||
movingItem = 0;
|
||||
}
|
||||
{}
|
||||
|
||||
void DiagramScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
QPointF mousePos(event->buttonDownScenePos(Qt::LeftButton).x(),
|
||||
event->buttonDownScenePos(Qt::LeftButton).y());
|
||||
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();
|
||||
}
|
||||
|
||||
clearSelection();
|
||||
QGraphicsScene::mousePressEvent(event);
|
||||
@ -76,11 +73,11 @@ void DiagramScene::mousePressEvent(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())
|
||||
emit itemMoved(qgraphicsitem_cast<DiagramItem *>(movingItem),
|
||||
oldPos);
|
||||
movingItem = 0;
|
||||
movingItem = nullptr;
|
||||
}
|
||||
QGraphicsScene::mouseReleaseEvent(event);
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ class DiagramScene : public QGraphicsScene
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DiagramScene(QObject *parent = 0);
|
||||
DiagramScene(QObject *parent = nullptr);
|
||||
|
||||
signals:
|
||||
void itemMoved(DiagramItem *movedItem, const QPointF &movedFromPosition);
|
||||
@ -76,7 +76,7 @@ protected:
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
|
||||
private:
|
||||
QGraphicsItem *movingItem;
|
||||
QGraphicsItem *movingItem = nullptr;
|
||||
QPointF oldPos;
|
||||
};
|
||||
//! [0]
|
||||
|
@ -48,7 +48,7 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtWidgets>
|
||||
#include <QApplication>
|
||||
|
||||
#include "mainwindow.h"
|
||||
|
||||
|
@ -48,13 +48,18 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
#include "mainwindow.h"
|
||||
#include "diagramscene.h"
|
||||
#include "diagramitem.h"
|
||||
#include "commands.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QGraphicsView>
|
||||
#include <QMenu>
|
||||
#include <QMenuBar>
|
||||
#include <QMessageBox>
|
||||
#include <QUndoView>
|
||||
|
||||
//! [0]
|
||||
MainWindow::MainWindow()
|
||||
{
|
||||
|
@ -87,22 +87,22 @@ private:
|
||||
void createMenus();
|
||||
void createUndoView();
|
||||
|
||||
QAction *deleteAction;
|
||||
QAction *addBoxAction;
|
||||
QAction *addTriangleAction;
|
||||
QAction *undoAction;
|
||||
QAction *redoAction;
|
||||
QAction *exitAction;
|
||||
QAction *aboutAction;
|
||||
QAction *deleteAction = nullptr;
|
||||
QAction *addBoxAction = nullptr;
|
||||
QAction *addTriangleAction = nullptr;
|
||||
QAction *undoAction = nullptr;
|
||||
QAction *redoAction = nullptr;
|
||||
QAction *exitAction = nullptr;
|
||||
QAction *aboutAction = nullptr;
|
||||
|
||||
QMenu *fileMenu;
|
||||
QMenu *editMenu;
|
||||
QMenu *itemMenu;
|
||||
QMenu *helpMenu;
|
||||
QMenu *fileMenu = nullptr;
|
||||
QMenu *editMenu = nullptr;
|
||||
QMenu *itemMenu = nullptr;
|
||||
QMenu *helpMenu = nullptr;
|
||||
|
||||
DiagramScene *diagramScene;
|
||||
QUndoStack *undoStack;
|
||||
QUndoView *undoView;
|
||||
DiagramScene *diagramScene = nullptr;
|
||||
QUndoStack *undoStack = nullptr;
|
||||
QUndoView *undoView = nullptr;
|
||||
};
|
||||
//! [0]
|
||||
|
||||
|
@ -14,7 +14,6 @@ include(unix.conf)
|
||||
|
||||
QMAKE_RESOURCE = /Developer/Tools/Rez
|
||||
QMAKE_EXTENSION_SHLIB = dylib
|
||||
QMAKE_EXTENSIONS_AUX_SHLIB = tbd
|
||||
QMAKE_LIBDIR =
|
||||
|
||||
# sdk.prf will prefix the proper SDK sysroot
|
||||
|
@ -300,7 +300,8 @@ mac {
|
||||
CMAKE_PRL_FILE_LOCATION_RELEASE = lib$${CMAKE_QT_STEM}.prl
|
||||
} else {
|
||||
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_BUILD_IS_FRAMEWORK = "true"
|
||||
} else {
|
||||
|
@ -22,6 +22,8 @@ for(ever) {
|
||||
!defined(QMAKE_LIBS_$$nu, var): \
|
||||
error("Library '$$lower($$replace(nu, _, -))' is not defined.")
|
||||
|
||||
QMAKE_LIBDIR += $$eval(QMAKE_LIBDIR_$$nu)
|
||||
|
||||
android {
|
||||
ABI_LIBS = $$eval(QMAKE_LIBS_$${nu}_$${QT_ARCH})
|
||||
isEmpty(ABI_LIBS): ABI_LIBS = $$eval(QMAKE_LIBS_$${nu})
|
||||
|
@ -537,98 +537,23 @@ defineReplace(qtGccSysrootifiedPaths) {
|
||||
return($$sysrootified)
|
||||
}
|
||||
|
||||
# libs-var, libs, in-paths, out-paths-var
|
||||
# libs-var, libs, in-paths
|
||||
defineTest(qtConfResolveLibs) {
|
||||
ret = true
|
||||
paths = $$3
|
||||
out =
|
||||
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
|
||||
for (path, 3): \
|
||||
pre_lflags += -L$$path
|
||||
$$1 = $$pre_lflags $$2
|
||||
export($$1)
|
||||
!isEmpty(4) {
|
||||
$$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)
|
||||
return(true)
|
||||
}
|
||||
|
||||
# libs-var, in-paths, libs
|
||||
defineTest(qtConfResolvePathLibs) {
|
||||
ret = true
|
||||
gcc: 2 = $$qtGccSysrootifiedPaths($$2)
|
||||
for (libdir, 2) {
|
||||
gcc: \
|
||||
local_paths = $$qtGccSysrootifiedPaths($$2)
|
||||
else: \
|
||||
local_paths = $$2
|
||||
for (libdir, local_paths) {
|
||||
!exists($$libdir/.) {
|
||||
qtLog("Library path $$val_escape(libdir) is invalid.")
|
||||
ret = false
|
||||
@ -678,8 +603,11 @@ defineReplace(qtConfGetTestIncludes) {
|
||||
# includes-var, in-paths, test-object-var
|
||||
defineTest(qtConfResolvePathIncs) {
|
||||
ret = true
|
||||
gcc: 2 = $$qtGccSysrootifiedPaths($$2)
|
||||
for (incdir, 2) {
|
||||
gcc: \
|
||||
local_paths = $$qtGccSysrootifiedPaths($$2)
|
||||
else: \
|
||||
local_paths = $$2
|
||||
for (incdir, local_paths) {
|
||||
!exists($$incdir/.) {
|
||||
qtLog("Include path $$val_escape(incdir) is invalid.")
|
||||
ret = false
|
||||
@ -773,11 +701,9 @@ defineTest(qtConfLibrary_inline) {
|
||||
for (ld, libdir): \
|
||||
libs += -L$$ld
|
||||
$${1}.libs = $$libs $$eval($${1}.libs)
|
||||
export($${1}.libs)
|
||||
}
|
||||
|
||||
!qtConfResolveAllLibs($$1): \
|
||||
return(false)
|
||||
|
||||
!qtConfResolvePathIncs($${1}.includedir, $$includes, $$2): \
|
||||
return(false)
|
||||
|
||||
|
@ -56,13 +56,13 @@ int main(int argc, char *argv[])
|
||||
QTranslator translator;
|
||||
// look up e.g. :/translations/myapp_de.qm
|
||||
if (translator.load(QLocale(), QLatin1String("myapp"), QLatin1String("_"), QLatin1String(":/translations")))
|
||||
app.installTranslator(&translator);
|
||||
QCoreApplication::installTranslator(&translator);
|
||||
|
||||
QPushButton hello(QCoreApplication::translate("main", "Hello world!"));
|
||||
hello.resize(100, 30);
|
||||
|
||||
hello.show();
|
||||
return app.exec();
|
||||
return QCoreApplication::exec();
|
||||
}
|
||||
//! [0]
|
||||
|
||||
|
@ -41,9 +41,9 @@
|
||||
#include "qfilesystemwatcher_p.h"
|
||||
|
||||
#include <qdatetime.h>
|
||||
#include <qdebug.h>
|
||||
#include <qdir.h>
|
||||
#include <qfileinfo.h>
|
||||
#include <qloggingcategory.h>
|
||||
#include <qset.h>
|
||||
#include <qtimer.h>
|
||||
|
||||
@ -67,6 +67,8 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
Q_LOGGING_CATEGORY(lcWatcher, "qt.core.filesystemwatcher")
|
||||
|
||||
QFileSystemWatcherEngine *QFileSystemWatcherPrivate::createNativeEngine(QObject *parent)
|
||||
{
|
||||
#if defined(Q_OS_WIN)
|
||||
@ -137,6 +139,7 @@ void QFileSystemWatcherPrivate::initPollerEngine()
|
||||
void QFileSystemWatcherPrivate::_q_fileChanged(const QString &path, bool removed)
|
||||
{
|
||||
Q_Q(QFileSystemWatcher);
|
||||
qCDebug(lcWatcher) << "file changed" << path << "removed?" << removed << "watching?" << files.contains(path);
|
||||
if (!files.contains(path)) {
|
||||
// the path was removed after a change was detected, but before we delivered the signal
|
||||
return;
|
||||
@ -149,6 +152,7 @@ void QFileSystemWatcherPrivate::_q_fileChanged(const QString &path, bool removed
|
||||
void QFileSystemWatcherPrivate::_q_directoryChanged(const QString &path, bool removed)
|
||||
{
|
||||
Q_Q(QFileSystemWatcher);
|
||||
qCDebug(lcWatcher) << "directory changed" << path << "removed?" << removed << "watching?" << directories.contains(path);
|
||||
if (!directories.contains(path)) {
|
||||
// perhaps the path was removed after a change was detected, but before we delivered the signal
|
||||
return;
|
||||
@ -355,7 +359,7 @@ QStringList QFileSystemWatcher::addPaths(const QStringList &paths)
|
||||
qWarning("QFileSystemWatcher::addPaths: list is empty");
|
||||
return p;
|
||||
}
|
||||
|
||||
qCDebug(lcWatcher) << "adding" << paths;
|
||||
const auto selectEngine = [this, d]() -> QFileSystemWatcherEngine* {
|
||||
#ifdef QT_BUILD_INTERNAL
|
||||
const QString on = objectName();
|
||||
@ -364,11 +368,11 @@ QStringList QFileSystemWatcher::addPaths(const QStringList &paths)
|
||||
// Autotest override case - use the explicitly selected engine only
|
||||
const QStringRef forceName = on.midRef(26);
|
||||
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();
|
||||
return d->poller;
|
||||
} 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 nullptr;
|
||||
@ -431,6 +435,7 @@ QStringList QFileSystemWatcher::removePaths(const QStringList &paths)
|
||||
qWarning("QFileSystemWatcher::removePaths: list is empty");
|
||||
return p;
|
||||
}
|
||||
qCDebug(lcWatcher) << "removing" << paths;
|
||||
|
||||
if (d->native)
|
||||
p = d->native->removePaths(p, &d->files, &d->directories);
|
||||
|
@ -2693,7 +2693,14 @@ Q_GLOBAL_STATIC(QRecursiveMutex, libraryPathMutex)
|
||||
QStringList QCoreApplication::libraryPaths()
|
||||
{
|
||||
QMutexLocker locker(libraryPathMutex());
|
||||
return libraryPathsLocked();
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
*/
|
||||
QStringList QCoreApplication::libraryPathsLocked()
|
||||
{
|
||||
if (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
|
||||
// around, and even create them if they don't exist, yet.
|
||||
if (!coreappdata()->app_libpaths)
|
||||
libraryPaths();
|
||||
libraryPathsLocked();
|
||||
|
||||
if (coreappdata()->manual_libpaths)
|
||||
*(coreappdata()->manual_libpaths) = paths;
|
||||
@ -2812,7 +2819,7 @@ void QCoreApplication::addLibraryPath(const QString &path)
|
||||
return;
|
||||
} else {
|
||||
// make sure that library paths are initialized
|
||||
libraryPaths();
|
||||
libraryPathsLocked();
|
||||
QStringList *app_libpaths = coreappdata()->app_libpaths.data();
|
||||
if (app_libpaths->contains(canonicalPath))
|
||||
return;
|
||||
@ -2851,7 +2858,7 @@ void QCoreApplication::removeLibraryPath(const QString &path)
|
||||
return;
|
||||
} else {
|
||||
// make sure that library paths is initialized
|
||||
libraryPaths();
|
||||
libraryPathsLocked();
|
||||
QStringList *app_libpaths = coreappdata()->app_libpaths.data();
|
||||
if (!app_libpaths->contains(canonicalPath))
|
||||
return;
|
||||
|
@ -208,6 +208,9 @@ private:
|
||||
static bool notifyInternal2(QObject *receiver, QEvent *);
|
||||
static bool forwardEvent(QObject *receiver, QEvent *event, QEvent *originatingEvent = nullptr);
|
||||
#endif
|
||||
#if QT_CONFIG(library)
|
||||
static QStringList libraryPathsLocked();
|
||||
#endif
|
||||
|
||||
static QCoreApplication *self;
|
||||
|
||||
|
@ -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");
|
||||
|
||||
template<typename U>
|
||||
struct TypeSelector
|
||||
{
|
||||
typedef QObject Type;
|
||||
};
|
||||
template<typename U>
|
||||
struct TypeSelector<const U>
|
||||
{
|
||||
typedef const QObject Type;
|
||||
};
|
||||
typedef typename TypeSelector<T>::Type QObjectType;
|
||||
using QObjectType =
|
||||
typename std::conditional<std::is_const<T>::value, const QObject, QObject>::type;
|
||||
QWeakPointer<QObjectType> wp;
|
||||
public:
|
||||
inline QPointer() { }
|
||||
QPointer() = default;
|
||||
inline QPointer(T *p) : wp(p, true) { }
|
||||
// compiler-generated copy/move ctor/assignment operators are fine!
|
||||
// compiler-generated dtor is fine!
|
||||
|
@ -48,6 +48,9 @@
|
||||
#include "qreadwritelock_p.h"
|
||||
#include "qelapsedtimer.h"
|
||||
#include "private/qfreelist_p.h"
|
||||
#include "private/qlocking_p.h"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@ -64,6 +67,9 @@ QT_BEGIN_NAMESPACE
|
||||
*/
|
||||
|
||||
namespace {
|
||||
|
||||
using ms = std::chrono::milliseconds;
|
||||
|
||||
enum {
|
||||
StateMask = 0x3,
|
||||
StateLockedForRead = 0x1,
|
||||
@ -262,7 +268,7 @@ bool QReadWriteLock::tryLockForRead(int timeout)
|
||||
if (d->recursive)
|
||||
return d->recursiveLockForRead(timeout);
|
||||
|
||||
QMutexLocker lock(&d->mutex);
|
||||
auto lock = qt_unique_lock(d->mutex);
|
||||
if (d != d_ptr.loadRelaxed()) {
|
||||
// d_ptr has changed: this QReadWriteLock was unlocked before we had
|
||||
// time to lock d->mutex.
|
||||
@ -273,7 +279,7 @@ bool QReadWriteLock::tryLockForRead(int timeout)
|
||||
d = d_ptr.loadAcquire();
|
||||
continue;
|
||||
}
|
||||
return d->lockForRead(timeout);
|
||||
return d->lockForRead(lock, timeout);
|
||||
}
|
||||
}
|
||||
|
||||
@ -369,7 +375,7 @@ bool QReadWriteLock::tryLockForWrite(int timeout)
|
||||
if (d->recursive)
|
||||
return d->recursiveLockForWrite(timeout);
|
||||
|
||||
QMutexLocker lock(&d->mutex);
|
||||
auto lock = qt_unique_lock(d->mutex);
|
||||
if (d != d_ptr.loadRelaxed()) {
|
||||
// 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
|
||||
@ -377,7 +383,7 @@ bool QReadWriteLock::tryLockForWrite(int timeout)
|
||||
d = d_ptr.loadAcquire();
|
||||
continue;
|
||||
}
|
||||
return d->lockForWrite(timeout);
|
||||
return d->lockForWrite(lock, timeout);
|
||||
}
|
||||
}
|
||||
|
||||
@ -418,7 +424,7 @@ void QReadWriteLock::unlock()
|
||||
return;
|
||||
}
|
||||
|
||||
QMutexLocker locker(&d->mutex);
|
||||
const auto lock = qt_scoped_lock(d->mutex);
|
||||
if (d->writerCount) {
|
||||
Q_ASSERT(d->writerCount == 1);
|
||||
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;
|
||||
if (timeout > 0)
|
||||
@ -476,10 +482,10 @@ bool QReadWriteLockPrivate::lockForRead(int timeout)
|
||||
if (elapsed > timeout)
|
||||
return false;
|
||||
waitingReaders++;
|
||||
readerCond.wait(&mutex, timeout - elapsed);
|
||||
readerCond.wait_for(lock, ms{timeout - elapsed});
|
||||
} else {
|
||||
waitingReaders++;
|
||||
readerCond.wait(&mutex);
|
||||
readerCond.wait(lock);
|
||||
}
|
||||
waitingReaders--;
|
||||
}
|
||||
@ -488,9 +494,9 @@ bool QReadWriteLockPrivate::lockForRead(int timeout)
|
||||
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;
|
||||
if (timeout > 0)
|
||||
@ -505,15 +511,15 @@ bool QReadWriteLockPrivate::lockForWrite(int timeout)
|
||||
if (waitingReaders && !waitingWriters && !writerCount) {
|
||||
// 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.
|
||||
readerCond.wakeAll();
|
||||
readerCond.notify_all();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
waitingWriters++;
|
||||
writerCond.wait(&mutex, timeout - elapsed);
|
||||
writerCond.wait_for(lock, ms{timeout - elapsed});
|
||||
} else {
|
||||
waitingWriters++;
|
||||
writerCond.wait(&mutex);
|
||||
writerCond.wait(lock);
|
||||
}
|
||||
waitingWriters--;
|
||||
}
|
||||
@ -526,17 +532,17 @@ bool QReadWriteLockPrivate::lockForWrite(int timeout)
|
||||
|
||||
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)
|
||||
writerCond.wakeOne();
|
||||
writerCond.notify_one();
|
||||
else if (waitingReaders)
|
||||
readerCond.wakeAll();
|
||||
readerCond.notify_all();
|
||||
}
|
||||
|
||||
bool QReadWriteLockPrivate::recursiveLockForRead(int timeout)
|
||||
{
|
||||
Q_ASSERT(recursive);
|
||||
QMutexLocker lock(&mutex);
|
||||
auto lock = qt_unique_lock(mutex);
|
||||
|
||||
Qt::HANDLE self = QThread::currentThreadId();
|
||||
|
||||
@ -546,7 +552,7 @@ bool QReadWriteLockPrivate::recursiveLockForRead(int timeout)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!lockForRead(timeout))
|
||||
if (!lockForRead(lock, timeout))
|
||||
return false;
|
||||
|
||||
currentReaders.insert(self, 1);
|
||||
@ -556,7 +562,7 @@ bool QReadWriteLockPrivate::recursiveLockForRead(int timeout)
|
||||
bool QReadWriteLockPrivate::recursiveLockForWrite(int timeout)
|
||||
{
|
||||
Q_ASSERT(recursive);
|
||||
QMutexLocker lock(&mutex);
|
||||
auto lock = qt_unique_lock(mutex);
|
||||
|
||||
Qt::HANDLE self = QThread::currentThreadId();
|
||||
if (currentWriter == self) {
|
||||
@ -564,7 +570,7 @@ bool QReadWriteLockPrivate::recursiveLockForWrite(int timeout)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!lockForWrite(timeout))
|
||||
if (!lockForWrite(lock, timeout))
|
||||
return false;
|
||||
|
||||
currentWriter = self;
|
||||
@ -574,7 +580,7 @@ bool QReadWriteLockPrivate::recursiveLockForWrite(int timeout)
|
||||
void QReadWriteLockPrivate::recursiveUnlock()
|
||||
{
|
||||
Q_ASSERT(recursive);
|
||||
QMutexLocker lock(&mutex);
|
||||
auto lock = qt_unique_lock(mutex);
|
||||
|
||||
Qt::HANDLE self = QThread::currentThreadId();
|
||||
if (self == currentWriter) {
|
||||
|
@ -54,7 +54,9 @@
|
||||
|
||||
#include <QtCore/private/qglobal_p.h>
|
||||
#include <QtCore/qhash.h>
|
||||
#include <QtCore/qwaitcondition.h>
|
||||
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
|
||||
QT_REQUIRE_CONFIG(thread);
|
||||
|
||||
@ -63,38 +65,36 @@ QT_BEGIN_NAMESPACE
|
||||
class QReadWriteLockPrivate
|
||||
{
|
||||
public:
|
||||
QReadWriteLockPrivate(bool isRecursive = false)
|
||||
: readerCount(0), writerCount(0), waitingReaders(0), waitingWriters(0),
|
||||
recursive(isRecursive), id(0), currentWriter(nullptr) {}
|
||||
explicit QReadWriteLockPrivate(bool isRecursive = false)
|
||||
: recursive(isRecursive) {}
|
||||
|
||||
QMutex mutex;
|
||||
QWaitCondition writerCond;
|
||||
QWaitCondition readerCond;
|
||||
int readerCount;
|
||||
int writerCount;
|
||||
int waitingReaders;
|
||||
int waitingWriters;
|
||||
std::mutex mutex;
|
||||
std::condition_variable writerCond;
|
||||
std::condition_variable readerCond;
|
||||
int readerCount = 0;
|
||||
int writerCount = 0;
|
||||
int waitingReaders = 0;
|
||||
int waitingWriters = 0;
|
||||
const bool recursive;
|
||||
|
||||
//Called with the mutex locked
|
||||
bool lockForWrite(int timeout);
|
||||
bool lockForRead(int timeout);
|
||||
bool lockForWrite(std::unique_lock<std::mutex> &lock, int timeout);
|
||||
bool lockForRead(std::unique_lock<std::mutex> &lock, int timeout);
|
||||
void unlock();
|
||||
|
||||
//memory management
|
||||
int id;
|
||||
int id = 0;
|
||||
void release();
|
||||
static QReadWriteLockPrivate *allocate();
|
||||
|
||||
// Recusive mutex handling
|
||||
Qt::HANDLE currentWriter;
|
||||
Qt::HANDLE currentWriter = {};
|
||||
QHash<Qt::HANDLE, int> currentReaders;
|
||||
|
||||
// called with the mutex unlocked
|
||||
bool recursiveLockForWrite(int timeout);
|
||||
bool recursiveLockForRead(int timeout);
|
||||
void recursiveUnlock();
|
||||
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -3432,15 +3432,15 @@ inline qint64 QDateTimePrivate::zoneMSecsToEpochMSecs(qint64 zoneMSecs, const QT
|
||||
datetime by adding a number of seconds, days, months, or years.
|
||||
|
||||
QDateTime can describe datetimes with respect to \l{Qt::LocalTime}{local
|
||||
time}, to \l{Qt::UTC}{UTC}, to a specified \l{Qt::OffsetFromUTC}{offset
|
||||
from UTC} or to a specified \l{Qt::TimeZone}{time zone}, in conjunction
|
||||
with the QTimeZone class. For example, a time zone of "Europe/Berlin" will
|
||||
apply the daylight-saving rules as used in Germany since 1970. In contrast,
|
||||
an offset from UTC of +3600 seconds is one hour ahead of UTC (usually
|
||||
written in ISO standard notation as "UTC+01:00"), with no daylight-saving
|
||||
offset or changes. When using either local time or a specified time zone,
|
||||
time-zone transitions such as the starts and ends of daylight-saving time
|
||||
(DST) are taken into account. The choice of system used to represent a
|
||||
time}, to \l{Qt::UTC}{UTC}, to a specified \l{Qt::OffsetFromUTC}{offset from
|
||||
UTC} or to a specified \l{Qt::TimeZone}{time zone}, in conjunction with the
|
||||
QTimeZone class. For example, a time zone of "Europe/Berlin" will apply the
|
||||
daylight-saving rules as used in Germany since 1970. In contrast, an offset
|
||||
from UTC of +3600 seconds is one hour ahead of UTC (usually written in ISO
|
||||
standard notation as "UTC+01:00"), with no daylight-saving offset or
|
||||
changes. When using either local time or a specified time zone, time-zone
|
||||
transitions such as the starts and ends of daylight-saving time (DST; but
|
||||
see below) are taken into account. The choice of system used to represent a
|
||||
datetime is described as its "timespec".
|
||||
|
||||
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
|
||||
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
|
||||
makes a \e{best guess} using the rules for year 1970 or 2037, but we can't
|
||||
guarantee accuracy. This means QDateTime doesn't take into account changes
|
||||
in a time zone before 1970, even if the system's time zone database provides
|
||||
that information.
|
||||
but these could change. For dates after 2037, QDateTime makes a \e{best
|
||||
guess} using the rules for year 2037, but we can't guarantee accuracy;
|
||||
indeed, for \e{any} future date, the time-zone may change its rules before
|
||||
that date comes around. For dates before 1970, QDateTime doesn't take DST
|
||||
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
|
||||
|
||||
@ -3797,17 +3799,22 @@ QTimeZone QDateTime::timeZone() const
|
||||
/*!
|
||||
\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
|
||||
Time Zone including any Daylight-Saving Offset.
|
||||
|
||||
If the timeSpec() is Qt::LocalTime this will be the difference between the
|
||||
Local Time and UTC including any Daylight-Saving Offset.
|
||||
|
||||
If the timeSpec() is Qt::UTC this will be 0.
|
||||
For the last two, the offset at this date and time will be returned, taking
|
||||
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
|
||||
given time-zone and UTC time; it is positive in time-zones ahead of UTC
|
||||
(East of The Prime Meridian), negative for those behind UTC (West of The
|
||||
Prime Meridian).
|
||||
|
||||
\sa setOffsetFromUtc()
|
||||
*/
|
||||
|
@ -371,6 +371,7 @@ QDate calculateTransitionLocalDate(const SYSTEMTIME &rule, int year)
|
||||
// Otherwise, the rule date is annual and relative:
|
||||
const int dayOfWeek = rule.wDayOfWeek == 0 ? 7 : rule.wDayOfWeek;
|
||||
QDate date(year, rule.wMonth, 1);
|
||||
Q_ASSERT(date.isValid());
|
||||
// How many days before was last dayOfWeek before target month ?
|
||||
int adjust = dayOfWeek - date.dayOfWeek(); // -6 <= adjust < 7
|
||||
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
|
||||
// WinTransitionRule; do this in init() once and store the results.
|
||||
Q_ASSERT(year);
|
||||
const QDate date = calculateTransitionLocalDate(rule, year);
|
||||
const QTime time = QTime(rule.wHour, rule.wMinute, rule.wSecond);
|
||||
if (date.isValid() && time.isValid())
|
||||
@ -479,6 +481,7 @@ struct TransitionTimePair
|
||||
|
||||
int yearEndOffset(const QWinTimeZonePrivate::QWinTransitionRule &rule, int year)
|
||||
{
|
||||
Q_ASSERT(year);
|
||||
int offset = rule.standardTimeBias;
|
||||
// Only needed to help another TransitionTimePair work out year + 1's start
|
||||
// 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);
|
||||
// Does this rule's period include any transition at all ?
|
||||
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) {
|
||||
const int newYearOffset = (year <= rule.startYear && ruleIndex > 0)
|
||||
? yearEndOffset(m_tranRules.at(ruleIndex - 1), year - 1)
|
||||
: yearEndOffset(rule, year - 1);
|
||||
? yearEndOffset(m_tranRules.at(ruleIndex - 1), prior)
|
||||
: yearEndOffset(rule, prior);
|
||||
const TransitionTimePair pair(rule, year, newYearOffset);
|
||||
bool isDst = false;
|
||||
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) {
|
||||
isDst = true;
|
||||
} 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;
|
||||
}
|
||||
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.
|
||||
return ruleToData(rule, forMSecsSinceEpoch, QTimeZone::StandardTime);
|
||||
}
|
||||
if (year >= rule.startYear)
|
||||
if (year >= rule.startYear) {
|
||||
year = rule.startYear - 1; // Seek last transition in new rule.
|
||||
if (!year)
|
||||
--year;
|
||||
}
|
||||
}
|
||||
// We don't have relevant data :-(
|
||||
return invalidData();
|
||||
@ -795,9 +803,10 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::nextTransition(qint64 afterMSecsSinc
|
||||
year = rule.startYear; // Seek first transition in this rule.
|
||||
const int endYear = ruleIndex + 1 < m_tranRules.count()
|
||||
? 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)
|
||||
? yearEndOffset(m_tranRules.at(ruleIndex - 1), year - 1)
|
||||
: yearEndOffset(rule, year - 1);
|
||||
? yearEndOffset(m_tranRules.at(ruleIndex - 1), prior)
|
||||
: yearEndOffset(rule, prior);
|
||||
while (year < endYear) {
|
||||
const TransitionTimePair pair(rule, year, newYearOffset);
|
||||
bool isDst = false;
|
||||
@ -810,7 +819,9 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::nextTransition(qint64 afterMSecsSinc
|
||||
newYearOffset = rule.standardTimeBias;
|
||||
if (pair.dst > pair.std)
|
||||
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;
|
||||
}
|
||||
|
||||
@ -837,11 +848,12 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::previousTransition(qint64 beforeMSec
|
||||
const QWinTransitionRule &rule = m_tranRules.at(ruleIndex);
|
||||
// Does this rule's period include any transition at all ?
|
||||
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) {
|
||||
const int newYearOffset = (year <= rule.startYear && ruleIndex > 0)
|
||||
? yearEndOffset(m_tranRules.at(ruleIndex - 1), year - 1)
|
||||
: yearEndOffset(rule, year - 1);
|
||||
? yearEndOffset(m_tranRules.at(ruleIndex - 1), prior)
|
||||
: yearEndOffset(rule, prior);
|
||||
const TransitionTimePair pair(rule, year, newYearOffset);
|
||||
bool isDst = false;
|
||||
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) {
|
||||
isDst = true;
|
||||
} 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;
|
||||
}
|
||||
if (isDst)
|
||||
@ -863,8 +876,11 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::previousTransition(qint64 beforeMSec
|
||||
// rule:
|
||||
return ruleToData(rule, startOfTime, QTimeZone::StandardTime, false);
|
||||
} // 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
|
||||
if (!year)
|
||||
--year;
|
||||
}
|
||||
}
|
||||
// Apparently no transition before the given time:
|
||||
return invalidData();
|
||||
|
@ -150,7 +150,7 @@
|
||||
// factory loader
|
||||
#include <qcoreapplication.h>
|
||||
#include <private/qfactoryloader_p.h>
|
||||
#include <QMutexLocker>
|
||||
#include <QtCore/private/qlocking_p.h>
|
||||
|
||||
// for qt_getImageText
|
||||
#include <private/qimage_p.h>
|
||||
@ -186,8 +186,8 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
|
||||
QByteArray suffix;
|
||||
|
||||
#ifndef QT_NO_IMAGEFORMATPLUGIN
|
||||
static QMutex mutex;
|
||||
QMutexLocker locker(&mutex);
|
||||
static QBasicMutex mutex;
|
||||
const auto locker = qt_scoped_lock(mutex);
|
||||
|
||||
typedef QMultiMap<int, QString> PluginKeyMap;
|
||||
|
||||
|
@ -57,6 +57,7 @@
|
||||
#include "qregexp.h"
|
||||
#include "qregion.h"
|
||||
#include "qdebug.h"
|
||||
#include <QtCore/private/qlocking_p.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@ -1427,7 +1428,7 @@ void qt_init_picture_plugins()
|
||||
typedef PluginKeyMap::const_iterator PluginKeyMapConstIterator;
|
||||
|
||||
static QBasicMutex mutex;
|
||||
QMutexLocker locker(&mutex);
|
||||
const auto locker = qt_scoped_lock(mutex);
|
||||
static QFactoryLoader loader(QPictureFormatInterface_iid,
|
||||
QStringLiteral("/pictureformats"));
|
||||
|
||||
|
@ -58,6 +58,7 @@
|
||||
#include <QtCore/private/qabstracteventdispatcher_p.h>
|
||||
#include <QtCore/qmutex.h>
|
||||
#include <QtCore/private/qthread_p.h>
|
||||
#include <QtCore/private/qlocking_p.h>
|
||||
#include <QtCore/qdir.h>
|
||||
#include <QtCore/qlibraryinfo.h>
|
||||
#include <QtCore/qnumeric.h>
|
||||
@ -3305,7 +3306,7 @@ void QGuiApplicationPrivate::applyWindowGeometrySpecificationTo(QWindow *window)
|
||||
QFont QGuiApplication::font()
|
||||
{
|
||||
Q_ASSERT_X(QGuiApplicationPrivate::self, "QGuiApplication::font()", "no QGuiApplication instance");
|
||||
QMutexLocker locker(&applicationFontMutex);
|
||||
const auto locker = qt_scoped_lock(applicationFontMutex);
|
||||
initFontUnlocked();
|
||||
return *QGuiApplicationPrivate::app_font;
|
||||
}
|
||||
@ -3317,7 +3318,7 @@ QFont QGuiApplication::font()
|
||||
*/
|
||||
void QGuiApplication::setFont(const QFont &font)
|
||||
{
|
||||
QMutexLocker locker(&applicationFontMutex);
|
||||
auto locker = qt_unique_lock(applicationFontMutex);
|
||||
const bool emitChange = !QGuiApplicationPrivate::app_font
|
||||
|| (*QGuiApplicationPrivate::app_font != font);
|
||||
if (!QGuiApplicationPrivate::app_font)
|
||||
@ -4081,7 +4082,7 @@ void QGuiApplicationPrivate::notifyThemeChanged()
|
||||
sendApplicationPaletteChange();
|
||||
}
|
||||
if (!(applicationResourceFlags & ApplicationFontExplicitlySet)) {
|
||||
QMutexLocker locker(&applicationFontMutex);
|
||||
const auto locker = qt_scoped_lock(applicationFontMutex);
|
||||
clearFontUnlocked();
|
||||
initFontUnlocked();
|
||||
}
|
||||
|
@ -680,8 +680,11 @@ QDpi QHighDpiScaling::logicalDpi(const QScreen *screen)
|
||||
if (!screen || !screen->handle())
|
||||
return QDpi(96, 96);
|
||||
|
||||
if (!m_usePixelDensity)
|
||||
return QPlatformScreen::overrideDpi(screen->handle()->logicalDpi());
|
||||
if (!m_usePixelDensity) {
|
||||
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 roundedScaleFactor = roundScaleFactor(scaleFactor);
|
||||
|
@ -45,6 +45,7 @@
|
||||
|
||||
#include <QtCore/QThreadStorage>
|
||||
#include <QtCore/QThread>
|
||||
#include <QtCore/private/qlocking_p.h>
|
||||
|
||||
#include <QtGui/private/qguiapplication_p.h>
|
||||
#include <QtGui/private/qopengl_p.h>
|
||||
@ -1442,7 +1443,7 @@ QOpenGLContextGroup *QOpenGLContextGroup::currentContextGroup()
|
||||
|
||||
void QOpenGLContextGroupPrivate::addContext(QOpenGLContext *ctx)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
const auto locker = qt_scoped_lock(m_mutex);
|
||||
m_refs.ref();
|
||||
m_shares << ctx;
|
||||
}
|
||||
@ -1454,7 +1455,7 @@ void QOpenGLContextGroupPrivate::removeContext(QOpenGLContext *ctx)
|
||||
bool deleteObject = false;
|
||||
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
const auto locker = qt_scoped_lock(m_mutex);
|
||||
m_shares.removeOne(ctx);
|
||||
|
||||
if (ctx == m_context && !m_shares.isEmpty())
|
||||
@ -1502,7 +1503,7 @@ void QOpenGLContextGroupPrivate::cleanup()
|
||||
|
||||
void QOpenGLContextGroupPrivate::deletePendingResources(QOpenGLContext *ctx)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
const auto locker = qt_scoped_lock(m_mutex);
|
||||
|
||||
const QList<QOpenGLSharedResource *> pending = m_pendingDeletion;
|
||||
m_pendingDeletion.clear();
|
||||
@ -1543,7 +1544,7 @@ void QOpenGLContextGroupPrivate::deletePendingResources(QOpenGLContext *ctx)
|
||||
QOpenGLSharedResource::QOpenGLSharedResource(QOpenGLContextGroup *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;
|
||||
}
|
||||
|
||||
@ -1559,7 +1560,7 @@ void QOpenGLSharedResource::free()
|
||||
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_pendingDeletion << this;
|
||||
|
||||
|
@ -228,7 +228,7 @@ TouchDevices::TouchDevices()
|
||||
*/
|
||||
QList<const QTouchDevice *> QTouchDevice::devices()
|
||||
{
|
||||
QMutexLocker lock(&devicesMutex);
|
||||
const auto locker = qt_scoped_lock(devicesMutex);
|
||||
return deviceList->list;
|
||||
}
|
||||
|
||||
@ -237,13 +237,13 @@ QList<const QTouchDevice *> QTouchDevice::devices()
|
||||
*/
|
||||
bool QTouchDevicePrivate::isRegistered(const QTouchDevice *dev)
|
||||
{
|
||||
QMutexLocker locker(&devicesMutex);
|
||||
const auto locker = qt_scoped_lock(devicesMutex);
|
||||
return deviceList->list.contains(dev);
|
||||
}
|
||||
|
||||
const QTouchDevice *QTouchDevicePrivate::deviceById(quint8 id)
|
||||
{
|
||||
QMutexLocker locker(&devicesMutex);
|
||||
const auto locker = qt_scoped_lock(devicesMutex);
|
||||
for (const QTouchDevice *dev : qAsConst(deviceList->list))
|
||||
if (QTouchDevicePrivate::get(const_cast<QTouchDevice *>(dev))->id == id)
|
||||
return dev;
|
||||
@ -255,7 +255,7 @@ const QTouchDevice *QTouchDevicePrivate::deviceById(quint8 id)
|
||||
*/
|
||||
void QTouchDevicePrivate::registerDevice(const QTouchDevice *dev)
|
||||
{
|
||||
QMutexLocker lock(&devicesMutex);
|
||||
const auto locker = qt_scoped_lock(devicesMutex);
|
||||
deviceList->list.append(dev);
|
||||
}
|
||||
|
||||
@ -264,7 +264,7 @@ void QTouchDevicePrivate::registerDevice(const QTouchDevice *dev)
|
||||
*/
|
||||
void QTouchDevicePrivate::unregisterDevice(const QTouchDevice *dev)
|
||||
{
|
||||
QMutexLocker lock(&devicesMutex);
|
||||
const auto locker = qt_scoped_lock(devicesMutex);
|
||||
deviceList->list.removeOne(dev);
|
||||
}
|
||||
|
||||
|
@ -62,17 +62,16 @@ class QColorVector
|
||||
{
|
||||
public:
|
||||
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
|
||||
: x(chr.x() / chr.y())
|
||||
, y(1.0f)
|
||||
, z((1.0 - chr.x() - chr.y()) / chr.y())
|
||||
, _unused(0.0f)
|
||||
{ }
|
||||
float x; // X, x or red
|
||||
float y; // Y, y or green
|
||||
float z; // Z, Y or blue
|
||||
float _unused;
|
||||
float x = 0.0f; // X, x or red
|
||||
float y = 0.0f; // Y, y or green
|
||||
float z = 0.0f; // Z, Y or blue
|
||||
float _unused = 0.0f;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static Q_DECL_CONSTEXPR QColorVector null() { return QColorVector(0.0f, 0.0f, 0.0f); }
|
||||
static bool isValidChromaticity(const QPointF &chr)
|
||||
{
|
||||
if (chr.x() < qreal(0.0) || chr.x() > qreal(1.0))
|
||||
@ -187,10 +185,6 @@ public:
|
||||
{ r.z, g.z, b.z } };
|
||||
}
|
||||
|
||||
static QColorMatrix null()
|
||||
{
|
||||
return { QColorVector::null(), QColorVector::null(), QColorVector::null() };
|
||||
}
|
||||
static QColorMatrix identity()
|
||||
{
|
||||
return { { 1.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f, 1.0f } };
|
||||
|
@ -146,17 +146,11 @@ QColorMatrix QColorSpacePrimaries::toXyzMatrix() const
|
||||
}
|
||||
|
||||
QColorSpacePrivate::QColorSpacePrivate()
|
||||
: primaries(QColorSpace::Primaries::Custom)
|
||||
, transferFunction(QColorSpace::TransferFunction::Custom)
|
||||
, gamma(0.0f)
|
||||
, whitePoint(QColorVector::null())
|
||||
, toXyz(QColorMatrix::null())
|
||||
{
|
||||
}
|
||||
|
||||
QColorSpacePrivate::QColorSpacePrivate(QColorSpace::NamedColorSpace namedColorSpace)
|
||||
: namedColorSpace(namedColorSpace)
|
||||
, gamma(0.0f)
|
||||
{
|
||||
switch (namedColorSpace) {
|
||||
case QColorSpace::SRgb:
|
||||
@ -282,7 +276,7 @@ void QColorSpacePrivate::initialize()
|
||||
void QColorSpacePrivate::setToXyzMatrix()
|
||||
{
|
||||
if (primaries == QColorSpace::Primaries::Custom) {
|
||||
toXyz = QColorMatrix::null();
|
||||
toXyz = QColorMatrix();
|
||||
whitePoint = QColorVector::D50();
|
||||
return;
|
||||
}
|
||||
|
@ -124,9 +124,9 @@ public:
|
||||
static constexpr QColorSpace::NamedColorSpace Unknown = QColorSpace::NamedColorSpace(0);
|
||||
QColorSpace::NamedColorSpace namedColorSpace = Unknown;
|
||||
|
||||
QColorSpace::Primaries primaries;
|
||||
QColorSpace::TransferFunction transferFunction;
|
||||
float gamma;
|
||||
QColorSpace::Primaries primaries = QColorSpace::Primaries::Custom;
|
||||
QColorSpace::TransferFunction transferFunction = QColorSpace::TransferFunction::Custom;
|
||||
float gamma = 0.0f;
|
||||
QColorVector whitePoint;
|
||||
|
||||
QColorTrc trc[3];
|
||||
|
@ -612,6 +612,15 @@ static void storeOpaque(QRgba64 *dst, const QRgba64 *src, const QColorVector *bu
|
||||
|
||||
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>
|
||||
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());
|
||||
|
||||
QColorVector buffer[WorkBlockSize];
|
||||
QUninitialized<QColorVector, WorkBlockSize> buffer;
|
||||
|
||||
qsizetype i = 0;
|
||||
while (i < count) {
|
||||
const qsizetype len = qMin(count - i, WorkBlockSize);
|
||||
|
209
src/gui/rhi/cs_tdr.h
Normal file
209
src/gui/rhi/cs_tdr.h
Normal 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
|
@ -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
|
||||
like QRhiCommandBuffer::debugMarkBegin() will become a no-op. Avoid
|
||||
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
|
||||
recoverable by attempting to repeat the operation (such as, beginFrame())
|
||||
and releasing and reinitializing all objects backed by native graphics
|
||||
resources.
|
||||
after releasing and reinitializing all objects backed by native graphics
|
||||
resources. See isDeviceLost().
|
||||
*/
|
||||
|
||||
/*!
|
||||
@ -673,7 +685,7 @@ bool operator!=(const QRhiDepthStencilClearValue &a, const QRhiDepthStencilClear
|
||||
*/
|
||||
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
|
||||
@ -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
|
||||
{
|
||||
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
|
||||
@ -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
|
||||
{
|
||||
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
|
||||
@ -1136,7 +1149,7 @@ bool operator!=(const QRhiVertexInputAttribute &a, const QRhiVertexInputAttribut
|
||||
*/
|
||||
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
|
||||
@ -3001,7 +3014,7 @@ bool operator!=(const QRhiShaderResourceBinding &a, const QRhiShaderResourceBind
|
||||
uint qHash(const QRhiShaderResourceBinding &b, uint seed) Q_DECL_NOTHROW
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
@ -3457,10 +3470,18 @@ QRhiResource::Type QRhiGraphicsPipeline::resourceType() const
|
||||
Flag values to describe swapchain properties
|
||||
|
||||
\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
|
||||
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
|
||||
render target views, where applicable. Note that this implies that sRGB
|
||||
@ -3823,8 +3844,8 @@ void QRhiImplementation::compressedFormatInfo(QRhiTexture::Format format, const
|
||||
break;
|
||||
}
|
||||
|
||||
const quint32 wblocks = (size.width() + xdim - 1) / xdim;
|
||||
const quint32 hblocks = (size.height() + ydim - 1) / ydim;
|
||||
const quint32 wblocks = uint((size.width() + xdim - 1) / xdim);
|
||||
const quint32 hblocks = uint((size.height() + ydim - 1) / ydim);
|
||||
|
||||
if (bpl)
|
||||
*bpl = wblocks * blockSize;
|
||||
@ -3880,9 +3901,9 @@ void QRhiImplementation::textureFormatInfo(QRhiTexture::Format format, const QSi
|
||||
}
|
||||
|
||||
if (bpl)
|
||||
*bpl = size.width() * bpc;
|
||||
*bpl = uint(size.width()) * bpc;
|
||||
if (byteSize)
|
||||
*byteSize = size.width() * size.height() * bpc;
|
||||
*byteSize = uint(size.width() * size.height()) * bpc;
|
||||
}
|
||||
|
||||
// Approximate because it excludes subresource alignment or multisampling.
|
||||
@ -3892,12 +3913,12 @@ quint32 QRhiImplementation::approxByteSizeForTexture(QRhiTexture::Format format,
|
||||
quint32 approxSize = 0;
|
||||
for (int level = 0; level < mipCount; ++level) {
|
||||
quint32 byteSize = 0;
|
||||
const QSize size(qFloor(float(qMax(1, baseSize.width() >> level))),
|
||||
qFloor(float(qMax(1, baseSize.height() >> level))));
|
||||
const QSize size(qFloor(qreal(qMax(1, baseSize.width() >> level))),
|
||||
qFloor(qreal(qMax(1, baseSize.height() >> level))));
|
||||
textureFormatInfo(format, size, nullptr, &byteSize);
|
||||
approxSize += byteSize;
|
||||
}
|
||||
approxSize *= layerCount;
|
||||
approxSize *= uint(layerCount);
|
||||
return approxSize;
|
||||
}
|
||||
|
||||
@ -5001,10 +5022,17 @@ const QRhiNativeHandles *QRhi::nativeHandles()
|
||||
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
|
||||
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();
|
||||
}
|
||||
|
||||
/*!
|
||||
\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.
|
||||
|
||||
@ -5197,7 +5272,17 @@ QRhiSwapChain *QRhi::newSwapChain()
|
||||
|
||||
\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)
|
||||
{
|
||||
@ -5222,7 +5307,17 @@ QRhi::FrameOpResult QRhi::beginFrame(QRhiSwapChain *swapChain, BeginFrameFlags f
|
||||
Passing QRhi::SkipPresent skips queuing the Present command or calling
|
||||
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)
|
||||
{
|
||||
|
@ -1294,7 +1294,8 @@ public:
|
||||
|
||||
enum Flag {
|
||||
EnableProfiling = 1 << 0,
|
||||
EnableDebugMarkers = 1 << 1
|
||||
EnableDebugMarkers = 1 << 1,
|
||||
PreferSoftwareRenderer = 1 << 2
|
||||
};
|
||||
Q_DECLARE_FLAGS(Flags, Flag)
|
||||
|
||||
@ -1413,7 +1414,7 @@ public:
|
||||
int resourceLimit(ResourceLimit limit) const;
|
||||
|
||||
const QRhiNativeHandles *nativeHandles();
|
||||
void makeThreadLocalNativeContextCurrent();
|
||||
bool makeThreadLocalNativeContextCurrent();
|
||||
|
||||
QRhiProfiler *profiler();
|
||||
|
||||
@ -1422,6 +1423,8 @@ public:
|
||||
|
||||
void releaseCachedResources();
|
||||
|
||||
bool isDeviceLost() const;
|
||||
|
||||
protected:
|
||||
QRhi();
|
||||
|
||||
|
@ -156,8 +156,9 @@ public:
|
||||
virtual int resourceLimit(QRhi::ResourceLimit limit) const = 0;
|
||||
virtual const QRhiNativeHandles *nativeHandles() = 0;
|
||||
virtual void sendVMemStatsToProfiler() = 0;
|
||||
virtual void makeThreadLocalNativeContextCurrent() = 0;
|
||||
virtual bool makeThreadLocalNativeContextCurrent() = 0;
|
||||
virtual void releaseCachedResources() = 0;
|
||||
virtual bool isDeviceLost() const = 0;
|
||||
|
||||
bool isCompressedFormat(QRhiTexture::Format format) const;
|
||||
void compressedFormatInfo(QRhiTexture::Format format, const QSize &size,
|
||||
|
@ -36,6 +36,7 @@
|
||||
|
||||
#include "qrhid3d11_p_p.h"
|
||||
#include "qshader_p.h"
|
||||
#include "cs_tdr.h"
|
||||
#include <QWindow>
|
||||
#include <QOperatingSystemVersion>
|
||||
#include <qmath.h>
|
||||
@ -118,10 +119,20 @@ QT_BEGIN_NAMESPACE
|
||||
\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)
|
||||
: ofr(this)
|
||||
: ofr(this),
|
||||
deviceCurse(this)
|
||||
{
|
||||
debugLayer = params->enableDebugLayer;
|
||||
|
||||
deviceCurse.framesToActivate = params->framesUntilKillingDeviceViaTdr;
|
||||
deviceCurse.permanent = params->repeatDeviceKill;
|
||||
|
||||
importedDevice = importDevice != nullptr;
|
||||
if (importedDevice) {
|
||||
dev = reinterpret_cast<ID3D11Device *>(importDevice->dev);
|
||||
@ -155,7 +166,7 @@ static QString comErrorMessage(HRESULT hr)
|
||||
}
|
||||
|
||||
template <class Int>
|
||||
static inline Int aligned(Int v, Int byteAlign)
|
||||
inline Int aligned(Int v, Int byteAlign)
|
||||
{
|
||||
return (v + byteAlign - 1) & ~(byteAlign - 1);
|
||||
}
|
||||
@ -166,7 +177,7 @@ static IDXGIFactory1 *createDXGIFactory2()
|
||||
if (QOperatingSystemVersion::current() > QOperatingSystemVersion::Windows7) {
|
||||
using PtrCreateDXGIFactory2 = HRESULT (WINAPI *)(UINT, REFIID, void **);
|
||||
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));
|
||||
if (FAILED(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;
|
||||
if (qEnvironmentVariableIsSet("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;
|
||||
adapter->GetDesc1(&desc);
|
||||
const QString name = QString::fromUtf16((char16_t *) desc.Description);
|
||||
qCDebug(QRHI_LOG_INFO, "Adapter %d: '%s' (flags 0x%x)", adapterIndex, qPrintable(name), desc.Flags);
|
||||
const QString name = QString::fromUtf16(reinterpret_cast<char16_t *>(desc.Description));
|
||||
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)) {
|
||||
adapterToUse = 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))))
|
||||
annotations = nullptr;
|
||||
|
||||
deviceLost = false;
|
||||
|
||||
nativeHandlesStruct.dev = dev;
|
||||
nativeHandlesStruct.context = context;
|
||||
|
||||
if (deviceCurse.framesToActivate > 0)
|
||||
deviceCurse.initResources();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -281,6 +315,8 @@ void QRhiD3D11::destroy()
|
||||
|
||||
clearShaderCache();
|
||||
|
||||
deviceCurse.releaseResources();
|
||||
|
||||
if (annotations) {
|
||||
annotations->Release();
|
||||
annotations = nullptr;
|
||||
@ -332,9 +368,9 @@ DXGI_SAMPLE_DESC QRhiD3D11::effectiveSampleCount(int sampleCount) const
|
||||
return desc;
|
||||
}
|
||||
|
||||
desc.Count = s;
|
||||
desc.Count = UINT(s);
|
||||
if (s > 1)
|
||||
desc.Quality = D3D11_STANDARD_MULTISAMPLE_PATTERN;
|
||||
desc.Quality = UINT(D3D11_STANDARD_MULTISAMPLE_PATTERN);
|
||||
else
|
||||
desc.Quality = 0;
|
||||
|
||||
@ -466,9 +502,10 @@ void QRhiD3D11::sendVMemStatsToProfiler()
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
void QRhiD3D11::makeThreadLocalNativeContextCurrent()
|
||||
bool QRhiD3D11::makeThreadLocalNativeContextCurrent()
|
||||
{
|
||||
// nothing to do here
|
||||
// not applicable
|
||||
return false;
|
||||
}
|
||||
|
||||
void QRhiD3D11::releaseCachedResources()
|
||||
@ -476,6 +513,11 @@ void QRhiD3D11::releaseCachedResources()
|
||||
clearShaderCache();
|
||||
}
|
||||
|
||||
bool QRhiD3D11::isDeviceLost() const
|
||||
{
|
||||
return deviceLost;
|
||||
}
|
||||
|
||||
QRhiRenderBuffer *QRhiD3D11::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
|
||||
int sampleCount, QRhiRenderBuffer::Flags flags)
|
||||
{
|
||||
@ -655,7 +697,7 @@ void QRhiD3D11::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind
|
||||
uint *p = cmd.args.bindShaderResources.dynamicOffsetPairs;
|
||||
for (int i = 0; i < dynamicOffsetCount; ++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);
|
||||
const uint offsetInConstants = dynOfs.second / 16;
|
||||
*p++ = binding;
|
||||
@ -791,10 +833,10 @@ void QRhiD3D11::setBlendConstants(QRhiCommandBuffer *cb, const QColor &c)
|
||||
QD3D11CommandBuffer::Command cmd;
|
||||
cmd.cmd = QD3D11CommandBuffer::Command::BlendConstants;
|
||||
cmd.args.blendConstants.ps = QRHI_RES(QD3D11GraphicsPipeline, cbD->currentGraphicsPipeline);
|
||||
cmd.args.blendConstants.c[0] = c.redF();
|
||||
cmd.args.blendConstants.c[1] = c.greenF();
|
||||
cmd.args.blendConstants.c[2] = c.blueF();
|
||||
cmd.args.blendConstants.c[3] = c.alphaF();
|
||||
cmd.args.blendConstants.c[0] = float(c.redF());
|
||||
cmd.args.blendConstants.c[1] = float(c.greenF());
|
||||
cmd.args.blendConstants.c[2] = float(c.blueF());
|
||||
cmd.args.blendConstants.c[3] = float(c.alphaF());
|
||||
cbD->commands.append(cmd);
|
||||
}
|
||||
|
||||
@ -992,8 +1034,14 @@ QRhi::FrameOpResult QRhiD3D11::endFrame(QRhiSwapChain *swapChain, QRhi::EndFrame
|
||||
if (!flags.testFlag(QRhi::SkipPresent)) {
|
||||
const UINT presentFlags = 0;
|
||||
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)));
|
||||
return QRhi::FrameOpError;
|
||||
}
|
||||
|
||||
// move on to the next buffer
|
||||
swapChainD->currentFrameSlot = (swapChainD->currentFrameSlot + 1) % QD3D11SwapChain::BUFFER_COUNT;
|
||||
@ -1003,6 +1051,20 @@ QRhi::FrameOpResult QRhiD3D11::endFrame(QRhiSwapChain *swapChain, QRhi::EndFrame
|
||||
|
||||
swapChainD->frameCount += 1;
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1176,7 +1238,7 @@ QRhi::FrameOpResult QRhiD3D11::finish()
|
||||
void QRhiD3D11::enqueueSubresUpload(QD3D11Texture *texD, QD3D11CommandBuffer *cbD,
|
||||
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();
|
||||
D3D11_BOX box;
|
||||
box.front = 0;
|
||||
@ -1207,13 +1269,13 @@ void QRhiD3D11::enqueueSubresUpload(QD3D11Texture *texD, QD3D11CommandBuffer *cb
|
||||
} else {
|
||||
cmd.args.updateSubRes.src = cbD->retainImage(img);
|
||||
}
|
||||
box.left = dp.x();
|
||||
box.top = dp.y();
|
||||
box.right = dp.x() + size.width();
|
||||
box.bottom = dp.y() + size.height();
|
||||
box.left = UINT(dp.x());
|
||||
box.top = UINT(dp.y());
|
||||
box.right = UINT(dp.x() + size.width());
|
||||
box.bottom = UINT(dp.y() + size.height());
|
||||
cmd.args.updateSubRes.hasDstBox = true;
|
||||
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)) {
|
||||
const QSize size = subresDesc.sourceSize().isEmpty() ? q->sizeForMipLevel(level, texD->m_pixelSize)
|
||||
: subresDesc.sourceSize();
|
||||
@ -1223,10 +1285,10 @@ void QRhiD3D11::enqueueSubresUpload(QD3D11Texture *texD, QD3D11CommandBuffer *cb
|
||||
// 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
|
||||
// comes to the actual data.
|
||||
box.left = aligned(dp.x(), blockDim.width());
|
||||
box.top = aligned(dp.y(), blockDim.height());
|
||||
box.right = aligned(dp.x() + size.width(), blockDim.width());
|
||||
box.bottom = aligned(dp.y() + size.height(), blockDim.height());
|
||||
box.left = UINT(aligned(dp.x(), blockDim.width()));
|
||||
box.top = UINT(aligned(dp.y(), blockDim.height()));
|
||||
box.right = UINT(aligned(dp.x() + size.width(), blockDim.width()));
|
||||
box.bottom = UINT(aligned(dp.y() + size.height(), blockDim.height()));
|
||||
cmd.args.updateSubRes.hasDstBox = true;
|
||||
cmd.args.updateSubRes.dstBox = box;
|
||||
cmd.args.updateSubRes.src = cbD->retainData(subresDesc.data());
|
||||
@ -1236,10 +1298,10 @@ void QRhiD3D11::enqueueSubresUpload(QD3D11Texture *texD, QD3D11CommandBuffer *cb
|
||||
: subresDesc.sourceSize();
|
||||
quint32 bpl = 0;
|
||||
textureFormatInfo(texD->m_format, size, &bpl, nullptr);
|
||||
box.left = dp.x();
|
||||
box.top = dp.y();
|
||||
box.right = dp.x() + size.width();
|
||||
box.bottom = dp.y() + size.height();
|
||||
box.left = UINT(dp.x());
|
||||
box.top = UINT(dp.y());
|
||||
box.right = UINT(dp.x() + size.width());
|
||||
box.bottom = UINT(dp.y() + size.height());
|
||||
cmd.args.updateSubRes.hasDstBox = true;
|
||||
cmd.args.updateSubRes.dstBox = box;
|
||||
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) {
|
||||
QD3D11Buffer *bufD = QRHI_RES(QD3D11Buffer, u.buf);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1279,10 +1341,10 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
|
||||
// since the ID3D11Buffer's size is rounded up to be a multiple of 256
|
||||
// while the data we have has the original size.
|
||||
D3D11_BOX box;
|
||||
box.left = u.offset;
|
||||
box.left = UINT(u.offset);
|
||||
box.top = box.front = 0;
|
||||
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.dstBox = box;
|
||||
cbD->commands.append(cmd);
|
||||
@ -1301,25 +1363,25 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
|
||||
Q_ASSERT(u.copy.src && u.copy.dst);
|
||||
QD3D11Texture *srcD = QRHI_RES(QD3D11Texture, u.copy.src);
|
||||
QD3D11Texture *dstD = QRHI_RES(QD3D11Texture, u.copy.dst);
|
||||
UINT srcSubRes = D3D11CalcSubresource(u.copy.desc.sourceLevel(), u.copy.desc.sourceLayer(), srcD->mipLevelCount);
|
||||
UINT dstSubRes = D3D11CalcSubresource(u.copy.desc.destinationLevel(), u.copy.desc.destinationLayer(), dstD->mipLevelCount);
|
||||
UINT srcSubRes = D3D11CalcSubresource(UINT(u.copy.desc.sourceLevel()), UINT(u.copy.desc.sourceLayer()), srcD->mipLevelCount);
|
||||
UINT dstSubRes = D3D11CalcSubresource(UINT(u.copy.desc.destinationLevel()), UINT(u.copy.desc.destinationLayer()), dstD->mipLevelCount);
|
||||
const QPoint dp = u.copy.desc.destinationTopLeft();
|
||||
const QSize size = u.copy.desc.pixelSize().isEmpty() ? srcD->m_pixelSize : u.copy.desc.pixelSize();
|
||||
const QPoint sp = u.copy.desc.sourceTopLeft();
|
||||
D3D11_BOX srcBox;
|
||||
srcBox.left = sp.x();
|
||||
srcBox.top = sp.y();
|
||||
srcBox.left = UINT(sp.x());
|
||||
srcBox.top = UINT(sp.y());
|
||||
srcBox.front = 0;
|
||||
// back, right, bottom are exclusive
|
||||
srcBox.right = srcBox.left + size.width();
|
||||
srcBox.bottom = srcBox.top + size.height();
|
||||
srcBox.right = srcBox.left + UINT(size.width());
|
||||
srcBox.bottom = srcBox.top + UINT(size.height());
|
||||
srcBox.back = 1;
|
||||
QD3D11CommandBuffer::Command cmd;
|
||||
cmd.cmd = QD3D11CommandBuffer::Command::CopySubRes;
|
||||
cmd.args.copySubRes.dst = dstD->tex;
|
||||
cmd.args.copySubRes.dstSubRes = dstSubRes;
|
||||
cmd.args.copySubRes.dstX = dp.x();
|
||||
cmd.args.copySubRes.dstY = dp.y();
|
||||
cmd.args.copySubRes.dstX = UINT(dp.x());
|
||||
cmd.args.copySubRes.dstY = UINT(dp.y());
|
||||
cmd.args.copySubRes.src = srcD->tex;
|
||||
cmd.args.copySubRes.srcSubRes = srcSubRes;
|
||||
cmd.args.copySubRes.hasSrcBox = true;
|
||||
@ -1347,7 +1409,7 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
|
||||
dxgiFormat = texD->dxgiFormat;
|
||||
pixelSize = u.read.rb.level() > 0 ? q->sizeForMipLevel(u.read.rb.level(), texD->m_pixelSize) : texD->m_pixelSize;
|
||||
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 {
|
||||
Q_ASSERT(contextState.currentSwapChain);
|
||||
swapChainD = QRHI_RES(QD3D11SwapChain, contextState.currentSwapChain);
|
||||
@ -1376,8 +1438,8 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
|
||||
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
memset(&desc, 0, sizeof(desc));
|
||||
desc.Width = pixelSize.width();
|
||||
desc.Height = pixelSize.height();
|
||||
desc.Width = UINT(pixelSize.width());
|
||||
desc.Height = UINT(pixelSize.height());
|
||||
desc.MipLevels = 1;
|
||||
desc.ArraySize = 1;
|
||||
desc.Format = dxgiFormat;
|
||||
@ -1390,7 +1452,7 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
|
||||
qWarning("Failed to create readback staging texture: %s", qPrintable(comErrorMessage(hr)));
|
||||
return;
|
||||
}
|
||||
QRHI_PROF_F(newReadbackBuffer(quint64(quintptr(stagingTex)),
|
||||
QRHI_PROF_F(newReadbackBuffer(qint64(qintptr(stagingTex)),
|
||||
texD ? static_cast<QRhiResource *>(texD) : static_cast<QRhiResource *>(swapChainD),
|
||||
bufSize));
|
||||
|
||||
@ -1433,7 +1495,7 @@ void QRhiD3D11::finishActiveReadbacks()
|
||||
const QRhiD3D11::ActiveReadback &aRb(activeReadbacks[i]);
|
||||
aRb.result->format = aRb.format;
|
||||
aRb.result->pixelSize = aRb.pixelSize;
|
||||
aRb.result->data.resize(aRb.bufSize);
|
||||
aRb.result->data.resize(int(aRb.bufSize));
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE 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);
|
||||
|
||||
aRb.stagingTex->Release();
|
||||
QRHI_PROF_F(releaseReadbackBuffer(quint64(quintptr(aRb.stagingTex))));
|
||||
QRHI_PROF_F(releaseReadbackBuffer(qint64(qintptr(aRb.stagingTex))));
|
||||
|
||||
if (aRb.result->completed)
|
||||
completedCallbacks.append(aRb.result->completed);
|
||||
@ -1523,10 +1585,10 @@ void QRhiD3D11::beginPass(QRhiCommandBuffer *cb,
|
||||
if (rtD->dsAttCount && wantsDsClear)
|
||||
clearCmd.args.clear.mask |= QD3D11CommandBuffer::Command::Depth | QD3D11CommandBuffer::Command::Stencil;
|
||||
|
||||
clearCmd.args.clear.c[0] = colorClearValue.redF();
|
||||
clearCmd.args.clear.c[1] = colorClearValue.greenF();
|
||||
clearCmd.args.clear.c[2] = colorClearValue.blueF();
|
||||
clearCmd.args.clear.c[3] = colorClearValue.alphaF();
|
||||
clearCmd.args.clear.c[0] = float(colorClearValue.redF());
|
||||
clearCmd.args.clear.c[1] = float(colorClearValue.greenF());
|
||||
clearCmd.args.clear.c[2] = float(colorClearValue.blueF());
|
||||
clearCmd.args.clear.c[3] = float(colorClearValue.alphaF());
|
||||
clearCmd.args.clear.d = depthStencilClearValue.depthClearValue();
|
||||
clearCmd.args.clear.s = depthStencilClearValue.stencilClearValue();
|
||||
cbD->commands.append(clearCmd);
|
||||
@ -1557,8 +1619,8 @@ void QRhiD3D11::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resource
|
||||
QD3D11CommandBuffer::Command cmd;
|
||||
cmd.cmd = QD3D11CommandBuffer::Command::ResolveSubRes;
|
||||
cmd.args.resolveSubRes.dst = dstTexD->tex;
|
||||
cmd.args.resolveSubRes.dstSubRes = D3D11CalcSubresource(colorAtt.resolveLevel(),
|
||||
colorAtt.resolveLayer(),
|
||||
cmd.args.resolveSubRes.dstSubRes = D3D11CalcSubresource(UINT(colorAtt.resolveLevel()),
|
||||
UINT(colorAtt.resolveLayer()),
|
||||
dstTexD->mipLevelCount);
|
||||
if (srcTexD) {
|
||||
cmd.args.resolveSubRes.src = srcTexD->tex;
|
||||
@ -1585,7 +1647,7 @@ void QRhiD3D11::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resource
|
||||
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;
|
||||
cbD->commands.append(cmd);
|
||||
}
|
||||
@ -1652,9 +1714,9 @@ void QRhiD3D11::dispatch(QRhiCommandBuffer *cb, int x, int y, int z)
|
||||
|
||||
QD3D11CommandBuffer::Command cmd;
|
||||
cmd.cmd = QD3D11CommandBuffer::Command::Dispatch;
|
||||
cmd.args.dispatch.x = x;
|
||||
cmd.args.dispatch.y = y;
|
||||
cmd.args.dispatch.z = z;
|
||||
cmd.args.dispatch.x = UINT(x);
|
||||
cmd.args.dispatch.y = UINT(y);
|
||||
cmd.args.dispatch.z = UINT(z);
|
||||
cbD->commands.append(cmd);
|
||||
}
|
||||
|
||||
@ -1696,11 +1758,11 @@ void QRhiD3D11::updateShaderResourceBindings(QD3D11ShaderResourceBindings *srbD)
|
||||
// dynamic ubuf offsets are not considered here, those are baked in
|
||||
// at a later stage, which is good as vsubufoffsets and friends are
|
||||
// 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).
|
||||
// We can round up if needed since the buffers's actual size
|
||||
// (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)) {
|
||||
srbD->vsubufs.feed(b->binding, bufD->buffer);
|
||||
srbD->vsubufoffsets.feed(b->binding, offsetInConstants);
|
||||
@ -1818,7 +1880,7 @@ void QRhiD3D11::executeBufferHostWritesForCurrentFrame(QD3D11Buffer *bufD)
|
||||
D3D11_MAPPED_SUBRESOURCE mp;
|
||||
HRESULT hr = context->Map(bufD->buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mp);
|
||||
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);
|
||||
} else {
|
||||
qWarning("Failed to map buffer: %s", qPrintable(comErrorMessage(hr)));
|
||||
@ -1831,13 +1893,13 @@ static void applyDynamicOffsets(QVarLengthArray<UINT, 4> *offsets,
|
||||
QRhiBatchedBindings<UINT> *ubufoffsets,
|
||||
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;
|
||||
*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) {
|
||||
const uint binding = dynOfsPairs[2 * di];
|
||||
if (binding == startBinding + b) {
|
||||
if (binding == startBinding + UINT(b)) {
|
||||
const uint offsetInConstants = dynOfsPairs[2 * di + 1];
|
||||
(*offsets)[b] = offsetInConstants;
|
||||
break;
|
||||
@ -1852,37 +1914,37 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
|
||||
{
|
||||
if (!offsetOnlyChange) {
|
||||
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) {
|
||||
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,
|
||||
batch.startBinding + batch.resources.count() - 1);
|
||||
int(batch.startBinding) + batch.resources.count() - 1);
|
||||
}
|
||||
|
||||
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) {
|
||||
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,
|
||||
batch.startBinding + batch.resources.count() - 1);
|
||||
int(batch.startBinding) + batch.resources.count() - 1);
|
||||
}
|
||||
|
||||
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) {
|
||||
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,
|
||||
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) {
|
||||
if (!dynOfsPairCount) {
|
||||
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->vsubufoffsets.batches[i].resources.constData(),
|
||||
srbD->vsubufsizes.batches[i].resources.constData());
|
||||
@ -1890,7 +1952,7 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
|
||||
QVarLengthArray<UINT, 4> offsets;
|
||||
applyDynamicOffsets(&offsets, i, &srbD->vsubufs, &srbD->vsubufoffsets, dynOfsPairs, dynOfsPairCount);
|
||||
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(),
|
||||
offsets.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) {
|
||||
if (!dynOfsPairCount) {
|
||||
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->fsubufoffsets.batches[i].resources.constData(),
|
||||
srbD->fsubufsizes.batches[i].resources.constData());
|
||||
@ -1908,7 +1970,7 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
|
||||
QVarLengthArray<UINT, 4> offsets;
|
||||
applyDynamicOffsets(&offsets, i, &srbD->fsubufs, &srbD->fsubufoffsets, dynOfsPairs, dynOfsPairCount);
|
||||
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(),
|
||||
offsets.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) {
|
||||
if (!dynOfsPairCount) {
|
||||
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->csubufoffsets.batches[i].resources.constData(),
|
||||
srbD->csubufsizes.batches[i].resources.constData());
|
||||
@ -1926,7 +1988,7 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
|
||||
QVarLengthArray<UINT, 4> offsets;
|
||||
applyDynamicOffsets(&offsets, i, &srbD->csubufs, &srbD->csubufoffsets, dynOfsPairs, dynOfsPairCount);
|
||||
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(),
|
||||
offsets.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) {
|
||||
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,
|
||||
count,
|
||||
srbD->csUAVs.batches[i].resources.constData(),
|
||||
nullptr);
|
||||
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);
|
||||
for (int i = 0; i < count; ++i)
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1978,15 +2040,15 @@ void QRhiD3D11::resetShaderResources()
|
||||
for (int i = 0; i < nullsrvs.count(); ++i)
|
||||
nullsrvs[i] = nullptr;
|
||||
if (contextState.vsHighestActiveSrvBinding >= 0) {
|
||||
context->VSSetShaderResources(0, contextState.vsHighestActiveSrvBinding + 1, nullsrvs.constData());
|
||||
context->VSSetShaderResources(0, UINT(contextState.vsHighestActiveSrvBinding + 1), nullsrvs.constData());
|
||||
contextState.vsHighestActiveSrvBinding = -1;
|
||||
}
|
||||
if (contextState.fsHighestActiveSrvBinding >= 0) {
|
||||
context->PSSetShaderResources(0, contextState.fsHighestActiveSrvBinding + 1, nullsrvs.constData());
|
||||
context->PSSetShaderResources(0, UINT(contextState.fsHighestActiveSrvBinding + 1), nullsrvs.constData());
|
||||
contextState.fsHighestActiveSrvBinding = -1;
|
||||
}
|
||||
if (contextState.csHighestActiveSrvBinding >= 0) {
|
||||
context->CSSetShaderResources(0, contextState.csHighestActiveSrvBinding + 1, nullsrvs.constData());
|
||||
context->CSSetShaderResources(0, UINT(contextState.csHighestActiveSrvBinding + 1), nullsrvs.constData());
|
||||
contextState.csHighestActiveSrvBinding = -1;
|
||||
}
|
||||
}
|
||||
@ -1997,7 +2059,7 @@ void QRhiD3D11::resetShaderResources()
|
||||
D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT> nulluavs(nulluavCount);
|
||||
for (int i = 0; i < nulluavCount; ++i)
|
||||
nulluavs[i] = nullptr;
|
||||
context->CSSetUnorderedAccessViews(0, nulluavCount, nulluavs.constData(), nullptr);
|
||||
context->CSSetUnorderedAccessViews(0, UINT(nulluavCount), nulluavs.constData(), nullptr);
|
||||
contextState.csHighestActiveUavBinding = -1;
|
||||
}
|
||||
}
|
||||
@ -2019,7 +2081,7 @@ void QRhiD3D11::executeCommandBuffer(QD3D11CommandBuffer *cbD, QD3D11SwapChain *
|
||||
// writing the first timestamp only afterwards.
|
||||
context->Begin(tsDisjoint);
|
||||
QD3D11RenderTargetData *rtD = rtData(×tampSwapChain->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
|
||||
}
|
||||
}
|
||||
@ -2032,7 +2094,7 @@ void QRhiD3D11::executeCommandBuffer(QD3D11CommandBuffer *cbD, QD3D11SwapChain *
|
||||
case QD3D11CommandBuffer::Command::SetRenderTarget:
|
||||
{
|
||||
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;
|
||||
case QD3D11CommandBuffer::Command::Clear:
|
||||
@ -2048,7 +2110,7 @@ void QRhiD3D11::executeCommandBuffer(QD3D11CommandBuffer *cbD, QD3D11SwapChain *
|
||||
if (cmd.args.clear.mask & QD3D11CommandBuffer::Command::Stencil)
|
||||
ds |= D3D11_CLEAR_STENCIL;
|
||||
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;
|
||||
case QD3D11CommandBuffer::Command::Viewport:
|
||||
@ -2078,8 +2140,8 @@ void QRhiD3D11::executeCommandBuffer(QD3D11CommandBuffer *cbD, QD3D11SwapChain *
|
||||
contextState.vsHighestActiveVertexBufferBinding = qMax<int>(
|
||||
contextState.vsHighestActiveVertexBufferBinding,
|
||||
cmd.args.bindVertexBuffers.startSlot + cmd.args.bindVertexBuffers.slotCount - 1);
|
||||
context->IASetVertexBuffers(cmd.args.bindVertexBuffers.startSlot,
|
||||
cmd.args.bindVertexBuffers.slotCount,
|
||||
context->IASetVertexBuffers(UINT(cmd.args.bindVertexBuffers.startSlot),
|
||||
UINT(cmd.args.bindVertexBuffers.slotCount),
|
||||
cmd.args.bindVertexBuffers.buffers,
|
||||
cmd.args.bindVertexBuffers.strides,
|
||||
cmd.args.bindVertexBuffers.offsets);
|
||||
@ -2222,7 +2284,7 @@ static inline uint toD3DBufferUsage(QRhiBuffer::UsageFlags usage)
|
||||
u |= D3D11_BIND_CONSTANT_BUFFER;
|
||||
if (usage.testFlag(QRhiBuffer::StorageBuffer))
|
||||
u |= D3D11_BIND_UNORDERED_ACCESS;
|
||||
return u;
|
||||
return uint(u);
|
||||
}
|
||||
|
||||
bool QD3D11Buffer::build()
|
||||
@ -2245,7 +2307,7 @@ bool QD3D11Buffer::build()
|
||||
|
||||
D3D11_BUFFER_DESC 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.BindFlags = toD3DBufferUsage(m_usage);
|
||||
desc.CPUAccessFlags = m_type == Dynamic ? D3D11_CPU_ACCESS_WRITE : 0;
|
||||
@ -2264,10 +2326,10 @@ bool QD3D11Buffer::build()
|
||||
}
|
||||
|
||||
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_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;
|
||||
rhiD->registerResource(this);
|
||||
@ -2285,7 +2347,7 @@ ID3D11UnorderedAccessView *QD3D11Buffer::unorderedAccessView()
|
||||
desc.Format = DXGI_FORMAT_R32_TYPELESS;
|
||||
desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
|
||||
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;
|
||||
|
||||
QRHI_RES_RHI(QRhiD3D11);
|
||||
@ -2346,8 +2408,8 @@ bool QD3D11RenderBuffer::build()
|
||||
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
memset(&desc, 0, sizeof(desc));
|
||||
desc.Width = m_pixelSize.width();
|
||||
desc.Height = m_pixelSize.height();
|
||||
desc.Width = UINT(m_pixelSize.width());
|
||||
desc.Height = UINT(m_pixelSize.height());
|
||||
desc.MipLevels = 1;
|
||||
desc.ArraySize = 1;
|
||||
desc.SampleDesc = sampleDesc;
|
||||
@ -2396,10 +2458,10 @@ bool QD3D11RenderBuffer::build()
|
||||
}
|
||||
|
||||
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_F(newRenderBuffer(this, false, false, sampleDesc.Count));
|
||||
QRHI_PROF_F(newRenderBuffer(this, false, false, int(sampleDesc.Count)));
|
||||
|
||||
rhiD->registerResource(this);
|
||||
return true;
|
||||
@ -2489,7 +2551,7 @@ bool QD3D11Texture::prepareBuild(QSize *adjustedSize)
|
||||
|
||||
QRHI_RES_RHI(QRhiD3D11);
|
||||
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);
|
||||
if (sampleDesc.Count > 1) {
|
||||
if (isCube) {
|
||||
@ -2575,8 +2637,8 @@ bool QD3D11Texture::build()
|
||||
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
memset(&desc, 0, sizeof(desc));
|
||||
desc.Width = size.width();
|
||||
desc.Height = size.height();
|
||||
desc.Width = UINT(size.width());
|
||||
desc.Height = UINT(size.height());
|
||||
desc.MipLevels = mipLevelCount;
|
||||
desc.ArraySize = isCube ? 6 : 1;
|
||||
desc.Format = dxgiFormat;
|
||||
@ -2596,10 +2658,10 @@ bool QD3D11Texture::build()
|
||||
return false;
|
||||
|
||||
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_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;
|
||||
rhiD->registerResource(this);
|
||||
@ -2621,7 +2683,7 @@ bool QD3D11Texture::buildFrom(const QRhiNativeHandles *src)
|
||||
return false;
|
||||
|
||||
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;
|
||||
QRHI_RES_RHI(QRhiD3D11);
|
||||
@ -2645,12 +2707,12 @@ ID3D11UnorderedAccessView *QD3D11Texture::unorderedAccessViewForLevel(int level)
|
||||
desc.Format = dxgiFormat;
|
||||
if (isCube) {
|
||||
desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY;
|
||||
desc.Texture2DArray.MipSlice = level;
|
||||
desc.Texture2DArray.MipSlice = UINT(level);
|
||||
desc.Texture2DArray.FirstArraySlice = 0;
|
||||
desc.Texture2DArray.ArraySize = 6;
|
||||
} else {
|
||||
desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
|
||||
desc.Texture2D.MipSlice = level;
|
||||
desc.Texture2D.MipSlice = UINT(level);
|
||||
}
|
||||
|
||||
QRHI_RES_RHI(QRhiD3D11);
|
||||
@ -2910,15 +2972,15 @@ bool QD3D11TextureRenderTarget::build()
|
||||
rtvDesc.Format = toD3DTextureFormat(texD->format(), texD->flags());
|
||||
if (texD->flags().testFlag(QRhiTexture::CubeMap)) {
|
||||
rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
|
||||
rtvDesc.Texture2DArray.MipSlice = colorAttachments[i].level();
|
||||
rtvDesc.Texture2DArray.FirstArraySlice = colorAttachments[i].layer();
|
||||
rtvDesc.Texture2DArray.MipSlice = UINT(colorAttachments[i].level());
|
||||
rtvDesc.Texture2DArray.FirstArraySlice = UINT(colorAttachments[i].layer());
|
||||
rtvDesc.Texture2DArray.ArraySize = 1;
|
||||
} else {
|
||||
if (texD->sampleDesc.Count > 1) {
|
||||
rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS;
|
||||
} else {
|
||||
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]);
|
||||
@ -2929,7 +2991,7 @@ bool QD3D11TextureRenderTarget::build()
|
||||
ownsRtv[i] = true;
|
||||
if (i == 0) {
|
||||
d.pixelSize = texD->pixelSize();
|
||||
d.sampleCount = texD->sampleDesc.Count;
|
||||
d.sampleCount = int(texD->sampleDesc.Count);
|
||||
}
|
||||
} else if (rb) {
|
||||
QD3D11RenderBuffer *rbD = QRHI_RES(QD3D11RenderBuffer, rb);
|
||||
@ -2937,7 +2999,7 @@ bool QD3D11TextureRenderTarget::build()
|
||||
rtv[i] = rbD->rtv;
|
||||
if (i == 0) {
|
||||
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) {
|
||||
d.pixelSize = depthTexD->pixelSize();
|
||||
d.sampleCount = depthTexD->sampleDesc.Count;
|
||||
d.sampleCount = int(depthTexD->sampleDesc.Count);
|
||||
}
|
||||
} else {
|
||||
ownsDsv = false;
|
||||
@ -2967,7 +3029,7 @@ bool QD3D11TextureRenderTarget::build()
|
||||
dsv = depthRbD->dsv;
|
||||
if (d.colorAttCount == 0) {
|
||||
d.pixelSize = m_desc.depthStencilBuffer()->pixelSize();
|
||||
d.sampleCount = depthRbD->sampleDesc.Count;
|
||||
d.sampleCount = int(depthRbD->sampleDesc.Count);
|
||||
}
|
||||
}
|
||||
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))
|
||||
f |= D3D11_COLOR_WRITE_ENABLE_RED;
|
||||
if (c.testFlag(QRhiGraphicsPipeline::G))
|
||||
@ -3328,22 +3390,22 @@ static QByteArray compileHlslShaderSource(const QShader &shader, QShader::Varian
|
||||
|
||||
ID3DBlob *bytecode = 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,
|
||||
hlslSource.entryPoint().constData(), target, 0, 0, &bytecode, &errors);
|
||||
if (FAILED(hr) || !bytecode) {
|
||||
qWarning("HLSL shader compilation failed: 0x%x", uint(hr));
|
||||
if (errors) {
|
||||
*error = QString::fromUtf8(static_cast<const char *>(errors->GetBufferPointer()),
|
||||
errors->GetBufferSize());
|
||||
int(errors->GetBufferSize()));
|
||||
errors->Release();
|
||||
}
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
QByteArray result;
|
||||
result.resize(bytecode->GetBufferSize());
|
||||
memcpy(result.data(), bytecode->GetBufferPointer(), result.size());
|
||||
result.resize(int(bytecode->GetBufferSize()));
|
||||
memcpy(result.data(), bytecode->GetBufferPointer(), size_t(result.size()));
|
||||
bytecode->Release();
|
||||
return result;
|
||||
}
|
||||
@ -3375,8 +3437,8 @@ bool QD3D11GraphicsPipeline::build()
|
||||
dsDesc.DepthFunc = toD3DCompareOp(m_depthOp);
|
||||
dsDesc.StencilEnable = m_stencilTest;
|
||||
if (m_stencilTest) {
|
||||
dsDesc.StencilReadMask = m_stencilReadMask;
|
||||
dsDesc.StencilWriteMask = m_stencilWriteMask;
|
||||
dsDesc.StencilReadMask = UINT8(m_stencilReadMask);
|
||||
dsDesc.StencilWriteMask = UINT8(m_stencilWriteMask);
|
||||
dsDesc.FrontFace.StencilFailOp = toD3DStencilOp(m_stencilFront.failOp);
|
||||
dsDesc.FrontFace.StencilDepthFailOp = toD3DStencilOp(m_stencilFront.depthFailOp);
|
||||
dsDesc.FrontFace.StencilPassOp = toD3DStencilOp(m_stencilFront.passOp);
|
||||
@ -3453,7 +3515,7 @@ bool QD3D11GraphicsPipeline::build()
|
||||
|
||||
switch (shaderStage.type()) {
|
||||
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)) {
|
||||
qWarning("Failed to create vertex shader: %s", qPrintable(comErrorMessage(hr)));
|
||||
return false;
|
||||
@ -3463,7 +3525,7 @@ bool QD3D11GraphicsPipeline::build()
|
||||
vs->AddRef();
|
||||
break;
|
||||
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)) {
|
||||
qWarning("Failed to create pixel shader: %s", qPrintable(comErrorMessage(hr)));
|
||||
return false;
|
||||
@ -3488,20 +3550,21 @@ bool QD3D11GraphicsPipeline::build()
|
||||
memset(&desc, 0, sizeof(desc));
|
||||
// the output from SPIRV-Cross uses TEXCOORD<location> as the semantic
|
||||
desc.SemanticName = "TEXCOORD";
|
||||
desc.SemanticIndex = attribute.location();
|
||||
desc.SemanticIndex = UINT(attribute.location());
|
||||
desc.Format = toD3DAttributeFormat(attribute.format());
|
||||
desc.InputSlot = attribute.binding();
|
||||
desc.InputSlot = UINT(attribute.binding());
|
||||
desc.AlignedByteOffset = attribute.offset();
|
||||
const QRhiVertexInputBinding &binding(bindings[attribute.binding()]);
|
||||
if (binding.classification() == QRhiVertexInputBinding::PerInstance) {
|
||||
desc.InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA;
|
||||
desc.InstanceDataStepRate = binding.instanceStepRate();
|
||||
desc.InstanceDataStepRate = UINT(binding.instanceStepRate());
|
||||
} else {
|
||||
desc.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
|
||||
}
|
||||
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)) {
|
||||
qWarning("Failed to create input layout: %s", qPrintable(comErrorMessage(hr)));
|
||||
return false;
|
||||
@ -3554,7 +3617,7 @@ bool QD3D11ComputePipeline::build()
|
||||
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)) {
|
||||
qWarning("Failed to create compute shader: %s", qPrintable(comErrorMessage(hr)));
|
||||
return false;
|
||||
@ -3690,8 +3753,8 @@ bool QD3D11SwapChain::newColorBuffer(const QSize &size, DXGI_FORMAT format, DXGI
|
||||
{
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
memset(&desc, 0, sizeof(desc));
|
||||
desc.Width = size.width();
|
||||
desc.Height = size.height();
|
||||
desc.Width = UINT(size.width());
|
||||
desc.Height = UINT(size.height());
|
||||
desc.MipLevels = 1;
|
||||
desc.ArraySize = 1;
|
||||
desc.Format = format;
|
||||
@ -3747,11 +3810,23 @@ bool QD3D11SwapChain::buildOrResize()
|
||||
const UINT swapChainFlags = 0;
|
||||
|
||||
QRHI_RES_RHI(QRhiD3D11);
|
||||
const bool useFlipDiscard = rhiD->hasDxgi2 && rhiD->supportsFlipDiscardSwapchain;
|
||||
bool useFlipDiscard = rhiD->hasDxgi2 && rhiD->supportsFlipDiscardSwapchain;
|
||||
if (!swapChain) {
|
||||
HWND hwnd = reinterpret_cast<HWND>(window->winId());
|
||||
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;
|
||||
if (useFlipDiscard) {
|
||||
// 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;
|
||||
memset(&desc, 0, sizeof(desc));
|
||||
desc.Width = pixelSize.width();
|
||||
desc.Height = pixelSize.height();
|
||||
desc.Width = UINT(pixelSize.width());
|
||||
desc.Height = UINT(pixelSize.height());
|
||||
desc.Format = colorFormat;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
desc.BufferCount = BUFFER_COUNT;
|
||||
desc.Scaling = DXGI_SCALING_STRETCH;
|
||||
desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||
if (m_flags.testFlag(SurfaceHasPreMulAlpha))
|
||||
desc.AlphaMode = DXGI_ALPHA_MODE_PREMULTIPLIED;
|
||||
else if (m_flags.testFlag(SurfaceHasNonPreMulAlpha))
|
||||
desc.AlphaMode = DXGI_ALPHA_MODE_STRAIGHT;
|
||||
// Do not bother with AlphaMode, if won't work unless we go through
|
||||
// DirectComposition. Instead, we just take the other (DISCARD)
|
||||
// path for now when alpha is requested.
|
||||
desc.Flags = swapChainFlags;
|
||||
|
||||
IDXGISwapChain1 *sc1;
|
||||
@ -3788,8 +3862,8 @@ bool QD3D11SwapChain::buildOrResize()
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC desc;
|
||||
memset(&desc, 0, sizeof(desc));
|
||||
desc.BufferDesc.Width = pixelSize.width();
|
||||
desc.BufferDesc.Height = pixelSize.height();
|
||||
desc.BufferDesc.Width = UINT(pixelSize.width());
|
||||
desc.BufferDesc.Height = UINT(pixelSize.height());
|
||||
desc.BufferDesc.RefreshRate.Numerator = 60;
|
||||
desc.BufferDesc.RefreshRate.Denominator = 1;
|
||||
desc.BufferDesc.Format = colorFormat;
|
||||
@ -3811,9 +3885,13 @@ bool QD3D11SwapChain::buildOrResize()
|
||||
} else {
|
||||
releaseBuffers();
|
||||
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);
|
||||
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)));
|
||||
return false;
|
||||
}
|
||||
@ -3874,13 +3952,13 @@ bool QD3D11SwapChain::buildOrResize()
|
||||
QD3D11ReferenceRenderTarget *rtD = QRHI_RES(QD3D11ReferenceRenderTarget, &rt);
|
||||
rtD->d.rp = QRHI_RES(QD3D11RenderPassDescriptor, m_renderPassDesc);
|
||||
rtD->d.pixelSize = pixelSize;
|
||||
rtD->d.dpr = window->devicePixelRatio();
|
||||
rtD->d.sampleCount = sampleDesc.Count;
|
||||
rtD->d.dpr = float(window->devicePixelRatio());
|
||||
rtD->d.sampleCount = int(sampleDesc.Count);
|
||||
rtD->d.colorAttCount = 1;
|
||||
rtD->d.dsAttCount = m_depthStencil ? 1 : 0;
|
||||
|
||||
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) {
|
||||
D3D11_QUERY_DESC queryDesc;
|
||||
memset(&queryDesc, 0, sizeof(queryDesc));
|
||||
@ -3914,4 +3992,34 @@ bool QD3D11SwapChain::buildOrResize()
|
||||
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
|
||||
|
@ -58,6 +58,9 @@ QT_BEGIN_NAMESPACE
|
||||
struct Q_GUI_EXPORT QRhiD3D11InitParams : public QRhiInitParams
|
||||
{
|
||||
bool enableDebugLayer = false;
|
||||
|
||||
int framesUntilKillingDeviceViaTdr = -1;
|
||||
bool repeatDeviceKill = false;
|
||||
};
|
||||
|
||||
struct Q_GUI_EXPORT QRhiD3D11NativeHandles : public QRhiNativeHandles
|
||||
|
@ -631,8 +631,9 @@ public:
|
||||
int resourceLimit(QRhi::ResourceLimit limit) const override;
|
||||
const QRhiNativeHandles *nativeHandles() override;
|
||||
void sendVMemStatsToProfiler() override;
|
||||
void makeThreadLocalNativeContextCurrent() override;
|
||||
bool makeThreadLocalNativeContextCurrent() override;
|
||||
void releaseCachedResources() override;
|
||||
bool isDeviceLost() const override;
|
||||
|
||||
void enqueueSubresUpload(QD3D11Texture *texD, QD3D11CommandBuffer *cbD,
|
||||
int layer, int level, const QRhiTextureSubresourceUploadDescription &subresDesc);
|
||||
@ -658,6 +659,7 @@ public:
|
||||
IDXGIFactory1 *dxgiFactory = nullptr;
|
||||
bool hasDxgi2 = false;
|
||||
bool supportsFlipDiscardSwapchain = false;
|
||||
bool deviceLost = false;
|
||||
QRhiD3D11NativeHandles nativeHandlesStruct;
|
||||
|
||||
struct {
|
||||
@ -694,6 +696,19 @@ public:
|
||||
QByteArray bytecode;
|
||||
};
|
||||
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);
|
||||
|
@ -371,7 +371,12 @@ bool QRhiGles2::ensureContext(QSurface *surface) const
|
||||
return true;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -491,6 +496,8 @@ bool QRhiGles2::create(QRhi::Flags flags)
|
||||
|
||||
nativeHandlesStruct.context = ctx;
|
||||
|
||||
contextLost = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -654,7 +661,7 @@ static inline GLenum toGlCompressedTextureFormat(QRhiTexture::Format format, QRh
|
||||
bool QRhiGles2::isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags) const
|
||||
{
|
||||
if (isCompressedFormat(format))
|
||||
return supportedCompressedFormats.contains(toGlCompressedTextureFormat(format, flags));
|
||||
return supportedCompressedFormats.contains(GLint(toGlCompressedTextureFormat(format, flags)));
|
||||
|
||||
switch (format) {
|
||||
case QRhiTexture::D16:
|
||||
@ -753,12 +760,12 @@ void QRhiGles2::sendVMemStatsToProfiler()
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
void QRhiGles2::makeThreadLocalNativeContextCurrent()
|
||||
bool QRhiGles2::makeThreadLocalNativeContextCurrent()
|
||||
{
|
||||
if (inFrame && !ofr.active)
|
||||
ensureContext(currentSwapChain->surface);
|
||||
return ensureContext(currentSwapChain->surface);
|
||||
else
|
||||
ensureContext();
|
||||
return ensureContext();
|
||||
}
|
||||
|
||||
void QRhiGles2::releaseCachedResources()
|
||||
@ -772,6 +779,11 @@ void QRhiGles2::releaseCachedResources()
|
||||
m_shaderCache.clear();
|
||||
}
|
||||
|
||||
bool QRhiGles2::isDeviceLost() const
|
||||
{
|
||||
return contextLost;
|
||||
}
|
||||
|
||||
QRhiRenderBuffer *QRhiGles2::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
|
||||
int sampleCount, QRhiRenderBuffer::Flags flags)
|
||||
{
|
||||
@ -930,7 +942,7 @@ void QRhiGles2::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind
|
||||
uint *p = cmd.args.bindShaderResources.dynamicOffsetPairs;
|
||||
for (int i = 0; i < dynamicOffsetCount; ++i) {
|
||||
const QRhiCommandBuffer::DynamicOffset &dynOfs(dynamicOffsets[i]);
|
||||
*p++ = dynOfs.first;
|
||||
*p++ = uint(dynOfs.first);
|
||||
*p++ = dynOfs.second;
|
||||
}
|
||||
} else {
|
||||
@ -1023,10 +1035,10 @@ void QRhiGles2::setBlendConstants(QRhiCommandBuffer *cb, const QColor &c)
|
||||
|
||||
QGles2CommandBuffer::Command cmd;
|
||||
cmd.cmd = QGles2CommandBuffer::Command::BlendConstants;
|
||||
cmd.args.blendConstants.r = c.redF();
|
||||
cmd.args.blendConstants.g = c.greenF();
|
||||
cmd.args.blendConstants.b = c.blueF();
|
||||
cmd.args.blendConstants.a = c.alphaF();
|
||||
cmd.args.blendConstants.r = float(c.redF());
|
||||
cmd.args.blendConstants.g = float(c.greenF());
|
||||
cmd.args.blendConstants.b = float(c.blueF());
|
||||
cmd.args.blendConstants.a = float(c.alphaF());
|
||||
cbD->commands.append(cmd);
|
||||
}
|
||||
|
||||
@ -1156,7 +1168,7 @@ QRhi::FrameOpResult QRhiGles2::beginFrame(QRhiSwapChain *swapChain, QRhi::BeginF
|
||||
|
||||
QGles2SwapChain *swapChainD = QRHI_RES(QGles2SwapChain, swapChain);
|
||||
if (!ensureContext(swapChainD->surface))
|
||||
return QRhi::FrameOpError;
|
||||
return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
|
||||
|
||||
currentSwapChain = swapChainD;
|
||||
|
||||
@ -1179,7 +1191,7 @@ QRhi::FrameOpResult QRhiGles2::endFrame(QRhiSwapChain *swapChain, QRhi::EndFrame
|
||||
addBoundaryCommand(&swapChainD->cb, QGles2CommandBuffer::Command::EndFrame);
|
||||
|
||||
if (!ensureContext(swapChainD->surface))
|
||||
return QRhi::FrameOpError;
|
||||
return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
|
||||
|
||||
executeCommandBuffer(&swapChainD->cb);
|
||||
|
||||
@ -1203,7 +1215,7 @@ QRhi::FrameOpResult QRhiGles2::beginOffscreenFrame(QRhiCommandBuffer **cb, QRhi:
|
||||
{
|
||||
Q_UNUSED(flags);
|
||||
if (!ensureContext())
|
||||
return QRhi::FrameOpError;
|
||||
return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
|
||||
|
||||
ofr.active = true;
|
||||
|
||||
@ -1225,7 +1237,7 @@ QRhi::FrameOpResult QRhiGles2::endOffscreenFrame(QRhi::EndFrameFlags flags)
|
||||
addBoundaryCommand(&ofr.cbWrapper, QGles2CommandBuffer::Command::EndFrame);
|
||||
|
||||
if (!ensureContext())
|
||||
return QRhi::FrameOpError;
|
||||
return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
|
||||
|
||||
executeCommandBuffer(&ofr.cbWrapper);
|
||||
|
||||
@ -1239,14 +1251,14 @@ QRhi::FrameOpResult QRhiGles2::finish()
|
||||
Q_ASSERT(!currentSwapChain);
|
||||
Q_ASSERT(ofr.cbWrapper.recordingPass == QGles2CommandBuffer::NoPass);
|
||||
if (!ensureContext())
|
||||
return QRhi::FrameOpError;
|
||||
return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
|
||||
executeCommandBuffer(&ofr.cbWrapper);
|
||||
ofr.cbWrapper.resetCommands();
|
||||
} else {
|
||||
Q_ASSERT(currentSwapChain);
|
||||
Q_ASSERT(currentSwapChain->cb.recordingPass == QGles2CommandBuffer::NoPass);
|
||||
if (!ensureContext(currentSwapChain->surface))
|
||||
return QRhi::FrameOpError;
|
||||
return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
|
||||
executeCommandBuffer(¤tSwapChain->cb);
|
||||
currentSwapChain->cb.resetCommands();
|
||||
}
|
||||
@ -1314,7 +1326,7 @@ void QRhiGles2::enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cb
|
||||
}
|
||||
cmd.args.subImage.target = texD->target;
|
||||
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.dx = dp.x();
|
||||
cmd.args.subImage.dy = dp.y();
|
||||
@ -1333,7 +1345,7 @@ void QRhiGles2::enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cb
|
||||
cmd.cmd = QGles2CommandBuffer::Command::CompressedSubImage;
|
||||
cmd.args.compressedSubImage.target = texD->target;
|
||||
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.dx = dp.x();
|
||||
cmd.args.compressedSubImage.dy = dp.y();
|
||||
@ -1348,7 +1360,7 @@ void QRhiGles2::enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cb
|
||||
cmd.cmd = QGles2CommandBuffer::Command::CompressedImage;
|
||||
cmd.args.compressedImage.target = texD->target;
|
||||
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.glintformat = texD->glintformat;
|
||||
cmd.args.compressedImage.w = size.width();
|
||||
@ -1366,7 +1378,7 @@ void QRhiGles2::enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cb
|
||||
cmd.cmd = QGles2CommandBuffer::Command::SubImage;
|
||||
cmd.args.subImage.target = texD->target;
|
||||
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.dx = dp.x();
|
||||
cmd.args.subImage.dy = dp.y();
|
||||
@ -1394,7 +1406,7 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
|
||||
QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, u.buf);
|
||||
Q_ASSERT(bufD->m_type == QRhiBuffer::Dynamic);
|
||||
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 {
|
||||
trackedBufferBarrier(cbD, bufD, QGles2Buffer::AccessUpdate);
|
||||
QGles2CommandBuffer::Command cmd;
|
||||
@ -1413,7 +1425,7 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
|
||||
Q_ASSERT(bufD->m_type != QRhiBuffer::Dynamic);
|
||||
Q_ASSERT(u.offset + u.data.size() <= bufD->m_size);
|
||||
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 {
|
||||
trackedBufferBarrier(cbD, bufD, QGles2Buffer::AccessUpdate);
|
||||
QGles2CommandBuffer::Command cmd;
|
||||
@ -1458,7 +1470,7 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
|
||||
QGles2CommandBuffer::Command cmd;
|
||||
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.srcLevel = u.copy.desc.sourceLevel();
|
||||
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.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.dstX = dp.x();
|
||||
cmd.args.copyTex.dstY = dp.y();
|
||||
@ -1480,7 +1492,8 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
|
||||
cmd.cmd = QGles2CommandBuffer::Command::ReadPixels;
|
||||
cmd.args.readPixels.result = u.read.result;
|
||||
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;
|
||||
if (texD) {
|
||||
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;
|
||||
const GLenum faceTargetBase = texD->m_flags.testFlag(QRhiTexture::CubeMap)
|
||||
? 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();
|
||||
}
|
||||
cbD->commands.append(cmd);
|
||||
@ -1848,7 +1861,7 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
|
||||
f->glBindVertexArray(0);
|
||||
break;
|
||||
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);
|
||||
break;
|
||||
case QGles2CommandBuffer::Command::Scissor:
|
||||
@ -1861,8 +1874,8 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
|
||||
{
|
||||
QGles2GraphicsPipeline *psD = QRHI_RES(QGles2GraphicsPipeline, cmd.args.stencilRef.ps);
|
||||
if (psD) {
|
||||
f->glStencilFuncSeparate(GL_FRONT, toGlCompareOp(psD->m_stencilFront.compareOp), 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_FRONT, toGlCompareOp(psD->m_stencilFront.compareOp), GLint(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 {
|
||||
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
|
||||
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;
|
||||
GLenum type = GL_FLOAT;
|
||||
bool normalize = false;
|
||||
@ -1924,13 +1937,13 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
|
||||
|
||||
const int locationIdx = a.location();
|
||||
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)));
|
||||
f->glEnableVertexAttribArray(locationIdx);
|
||||
f->glEnableVertexAttribArray(GLuint(locationIdx));
|
||||
if (bindings[bindingIdx].classification() == QRhiVertexInputBinding::PerInstance
|
||||
&& caps.instancing)
|
||||
{
|
||||
f->glVertexAttribDivisor(locationIdx, bindings[bindingIdx].instanceStepRate());
|
||||
f->glVertexAttribDivisor(GLuint(locationIdx), GLuint(bindings[bindingIdx].instanceStepRate()));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -1949,10 +1962,10 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
|
||||
QGles2GraphicsPipeline *psD = QRHI_RES(QGles2GraphicsPipeline, cmd.args.draw.ps);
|
||||
if (psD) {
|
||||
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 {
|
||||
f->glDrawArraysInstanced(psD->drawMode, cmd.args.draw.firstVertex, cmd.args.draw.vertexCount,
|
||||
cmd.args.draw.instanceCount);
|
||||
f->glDrawArraysInstanced(psD->drawMode, GLint(cmd.args.draw.firstVertex), GLsizei(cmd.args.draw.vertexCount),
|
||||
GLsizei(cmd.args.draw.instanceCount));
|
||||
}
|
||||
} else {
|
||||
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.baseVertex != 0 && caps.baseVertex) {
|
||||
f->glDrawElementsBaseVertex(psD->drawMode,
|
||||
cmd.args.drawIndexed.indexCount,
|
||||
GLsizei(cmd.args.drawIndexed.indexCount),
|
||||
indexType,
|
||||
ofs,
|
||||
cmd.args.drawIndexed.baseVertex);
|
||||
} else {
|
||||
f->glDrawElements(psD->drawMode,
|
||||
cmd.args.drawIndexed.indexCount,
|
||||
GLsizei(cmd.args.drawIndexed.indexCount),
|
||||
indexType,
|
||||
ofs);
|
||||
}
|
||||
} else {
|
||||
if (cmd.args.drawIndexed.baseVertex != 0 && caps.baseVertex) {
|
||||
f->glDrawElementsInstancedBaseVertex(psD->drawMode,
|
||||
cmd.args.drawIndexed.indexCount,
|
||||
GLsizei(cmd.args.drawIndexed.indexCount),
|
||||
indexType,
|
||||
ofs,
|
||||
cmd.args.drawIndexed.instanceCount,
|
||||
GLsizei(cmd.args.drawIndexed.instanceCount),
|
||||
cmd.args.drawIndexed.baseVertex);
|
||||
} else {
|
||||
f->glDrawElementsInstanced(psD->drawMode,
|
||||
cmd.args.drawIndexed.indexCount,
|
||||
GLsizei(cmd.args.drawIndexed.indexCount),
|
||||
indexType,
|
||||
ofs,
|
||||
cmd.args.drawIndexed.instanceCount);
|
||||
GLsizei(cmd.args.drawIndexed.instanceCount));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -2016,7 +2029,7 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
|
||||
const int colorAttCount = cmd.args.bindFramebuffer.colorAttCount;
|
||||
QVarLengthArray<GLenum, 8> bufs;
|
||||
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());
|
||||
}
|
||||
} else {
|
||||
@ -2044,7 +2057,7 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
|
||||
f->glClearDepthf(cmd.args.clear.d);
|
||||
}
|
||||
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);
|
||||
break;
|
||||
case QGles2CommandBuffer::Command::BufferSubData:
|
||||
@ -2288,7 +2301,7 @@ void QRhiGles2::bindShaderResources(QRhiGraphicsPipeline *maybeGraphicsPs, QRhiC
|
||||
if (dynOfsCount) {
|
||||
for (int j = 0; j < dynOfsCount; ++j) {
|
||||
if (dynOfsPairs[2 * j] == uint(b->binding)) {
|
||||
viewOffset = dynOfsPairs[2 * j + 1];
|
||||
viewOffset = int(dynOfsPairs[2 * j + 1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2379,20 +2392,20 @@ void QRhiGles2::bindShaderResources(QRhiGraphicsPipeline *maybeGraphicsPs, QRhiC
|
||||
|
||||
for (QGles2SamplerDescription &sampler : samplers) {
|
||||
if (sampler.binding == b->binding) {
|
||||
f->glActiveTexture(GL_TEXTURE0 + texUnit);
|
||||
f->glActiveTexture(GL_TEXTURE0 + uint(texUnit));
|
||||
f->glBindTexture(texD->target, texD->texture);
|
||||
|
||||
if (texD->samplerState != samplerD->d) {
|
||||
f->glTexParameteri(texD->target, GL_TEXTURE_MIN_FILTER, samplerD->d.glminfilter);
|
||||
f->glTexParameteri(texD->target, GL_TEXTURE_MAG_FILTER, samplerD->d.glmagfilter);
|
||||
f->glTexParameteri(texD->target, GL_TEXTURE_WRAP_S, samplerD->d.glwraps);
|
||||
f->glTexParameteri(texD->target, GL_TEXTURE_WRAP_T, samplerD->d.glwrapt);
|
||||
f->glTexParameteri(texD->target, GL_TEXTURE_MIN_FILTER, GLint(samplerD->d.glminfilter));
|
||||
f->glTexParameteri(texD->target, GL_TEXTURE_MAG_FILTER, GLint(samplerD->d.glmagfilter));
|
||||
f->glTexParameteri(texD->target, GL_TEXTURE_WRAP_S, GLint(samplerD->d.glwraps));
|
||||
f->glTexParameteri(texD->target, GL_TEXTURE_WRAP_T, GLint(samplerD->d.glwrapt));
|
||||
// 3D textures not supported by GLES 2.0 or by us atm...
|
||||
//f->glTexParameteri(texD->target, GL_TEXTURE_WRAP_R, samplerD->d.glwrapr);
|
||||
if (caps.textureCompareMode) {
|
||||
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_FUNC, samplerD->d.gltexcomparefunc);
|
||||
f->glTexParameteri(texD->target, GL_TEXTURE_COMPARE_FUNC, GLint(samplerD->d.gltexcomparefunc));
|
||||
} else {
|
||||
f->glTexParameteri(texD->target, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
||||
}
|
||||
@ -2419,7 +2432,7 @@ void QRhiGles2::bindShaderResources(QRhiGraphicsPipeline *maybeGraphicsPs, QRhiC
|
||||
access = GL_READ_ONLY;
|
||||
else if (b->type == QRhiShaderResourceBinding::ImageStore)
|
||||
access = GL_WRITE_ONLY;
|
||||
f->glBindImageTexture(b->binding, texD->texture,
|
||||
f->glBindImageTexture(GLuint(b->binding), texD->texture,
|
||||
b->u.simage.level, layered, 0,
|
||||
access, texD->glsizedintformat);
|
||||
}
|
||||
@ -2432,9 +2445,9 @@ void QRhiGles2::bindShaderResources(QRhiGraphicsPipeline *maybeGraphicsPs, QRhiC
|
||||
{
|
||||
QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, b->u.sbuf.buf);
|
||||
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
|
||||
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);
|
||||
}
|
||||
break;
|
||||
@ -2556,10 +2569,10 @@ void QRhiGles2::beginPass(QRhiCommandBuffer *cb,
|
||||
clearCmd.args.clear.mask |= GL_COLOR_BUFFER_BIT;
|
||||
if (rtD->dsAttCount && wantsDsClear)
|
||||
clearCmd.args.clear.mask |= GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
|
||||
clearCmd.args.clear.c[0] = colorClearValue.redF();
|
||||
clearCmd.args.clear.c[1] = colorClearValue.greenF();
|
||||
clearCmd.args.clear.c[2] = colorClearValue.blueF();
|
||||
clearCmd.args.clear.c[3] = colorClearValue.alphaF();
|
||||
clearCmd.args.clear.c[0] = float(colorClearValue.redF());
|
||||
clearCmd.args.clear.c[1] = float(colorClearValue.greenF());
|
||||
clearCmd.args.clear.c[2] = float(colorClearValue.blueF());
|
||||
clearCmd.args.clear.c[3] = float(colorClearValue.alphaF());
|
||||
clearCmd.args.clear.d = depthStencilClearValue.depthClearValue();
|
||||
clearCmd.args.clear.s = depthStencilClearValue.stencilClearValue();
|
||||
cbD->commands.append(clearCmd);
|
||||
@ -2597,7 +2610,7 @@ void QRhiGles2::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resource
|
||||
QGles2Texture *colorTexD = QRHI_RES(QGles2Texture, colorAtt.resolveTexture());
|
||||
const GLenum faceTargetBase = colorTexD->m_flags.testFlag(QRhiTexture::CubeMap) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X
|
||||
: 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.dstLevel = colorAtt.resolveLevel();
|
||||
cbD->commands.append(cmd);
|
||||
@ -2664,9 +2677,9 @@ void QRhiGles2::dispatch(QRhiCommandBuffer *cb, int x, int y, int z)
|
||||
|
||||
QGles2CommandBuffer::Command cmd;
|
||||
cmd.cmd = QGles2CommandBuffer::Command::Dispatch;
|
||||
cmd.args.dispatch.x = x;
|
||||
cmd.args.dispatch.y = y;
|
||||
cmd.args.dispatch.z = z;
|
||||
cmd.args.dispatch.x = GLuint(x);
|
||||
cmd.args.dispatch.y = GLuint(y);
|
||||
cmd.args.dispatch.z = GLuint(z);
|
||||
cbD->commands.append(cmd);
|
||||
}
|
||||
|
||||
@ -2818,7 +2831,7 @@ void QRhiGles2::gatherUniforms(GLuint program, const QShaderDescription::Uniform
|
||||
uniform.glslLocation = f->glGetUniformLocation(program, name.constData());
|
||||
if (uniform.glslLocation >= 0) {
|
||||
uniform.binding = ub.binding;
|
||||
uniform.offset = blockMember.offset;
|
||||
uniform.offset = uint(blockMember.offset);
|
||||
uniform.size = blockMember.size;
|
||||
dst->append(uniform);
|
||||
}
|
||||
@ -2882,7 +2895,7 @@ bool QGles2Buffer::build()
|
||||
return false;
|
||||
}
|
||||
ubuf.resize(nonZeroSize);
|
||||
QRHI_PROF_F(newBuffer(this, nonZeroSize, 0, 1));
|
||||
QRHI_PROF_F(newBuffer(this, uint(nonZeroSize), 0, 1));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2901,7 +2914,7 @@ bool QGles2Buffer::build()
|
||||
|
||||
usageState.access = AccessNone;
|
||||
|
||||
QRHI_PROF_F(newBuffer(this, nonZeroSize, 1, 0));
|
||||
QRHI_PROF_F(newBuffer(this, uint(nonZeroSize), 1, 0));
|
||||
rhiD->registerResource(this);
|
||||
return true;
|
||||
}
|
||||
@ -3172,13 +3185,13 @@ bool QGles2Texture::build()
|
||||
for (int layer = 0, layerCount = isCube ? 6 : 1; layer != layerCount; ++layer) {
|
||||
for (int level = 0; level != mipLevelCount; ++level) {
|
||||
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,
|
||||
glformat, gltype, nullptr);
|
||||
}
|
||||
}
|
||||
} 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);
|
||||
}
|
||||
} else {
|
||||
@ -3381,14 +3394,15 @@ bool QGles2TextureRenderTarget::build()
|
||||
QGles2Texture *texD = QRHI_RES(QGles2Texture, texture);
|
||||
Q_ASSERT(texD->texture && texD->specified);
|
||||
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) {
|
||||
d.pixelSize = texD->pixelSize();
|
||||
d.sampleCount = 1;
|
||||
}
|
||||
} else if (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) {
|
||||
d.pixelSize = rbD->pixelSize();
|
||||
d.sampleCount = rbD->samples;
|
||||
@ -3538,7 +3552,7 @@ bool QGles2GraphicsPipeline::build()
|
||||
|
||||
for (auto inVar : vsDesc.inputVariables()) {
|
||||
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))
|
||||
@ -3684,7 +3698,7 @@ bool QGles2SwapChain::buildOrResize()
|
||||
|
||||
rt.d.rp = QRHI_RES(QGles2RenderPassDescriptor, m_renderPassDesc);
|
||||
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.colorAttCount = 1;
|
||||
rt.d.dsAttCount = m_depthStencil ? 1 : 0;
|
||||
|
@ -664,8 +664,9 @@ public:
|
||||
int resourceLimit(QRhi::ResourceLimit limit) const override;
|
||||
const QRhiNativeHandles *nativeHandles() override;
|
||||
void sendVMemStatsToProfiler() override;
|
||||
void makeThreadLocalNativeContextCurrent() override;
|
||||
bool makeThreadLocalNativeContextCurrent() override;
|
||||
void releaseCachedResources() override;
|
||||
bool isDeviceLost() const override;
|
||||
|
||||
bool ensureContext(QSurface *surface = nullptr) const;
|
||||
void executeDeferredReleases();
|
||||
@ -769,6 +770,7 @@ public:
|
||||
QVector<GLint> supportedCompressedFormats;
|
||||
mutable QVector<int> supportedSampleCountList;
|
||||
QRhiGles2NativeHandles nativeHandlesStruct;
|
||||
mutable bool contextLost = false;
|
||||
|
||||
struct DeferredReleaseEntry {
|
||||
enum Type {
|
||||
|
@ -352,7 +352,8 @@ QRhiMetal::~QRhiMetal()
|
||||
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);
|
||||
}
|
||||
@ -582,9 +583,10 @@ void QRhiMetal::sendVMemStatsToProfiler()
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
void QRhiMetal::makeThreadLocalNativeContextCurrent()
|
||||
bool QRhiMetal::makeThreadLocalNativeContextCurrent()
|
||||
{
|
||||
// nothing to do here
|
||||
// not applicable
|
||||
return false;
|
||||
}
|
||||
|
||||
void QRhiMetal::releaseCachedResources()
|
||||
@ -595,6 +597,11 @@ void QRhiMetal::releaseCachedResources()
|
||||
d->shaderCache.clear();
|
||||
}
|
||||
|
||||
bool QRhiMetal::isDeviceLost() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QRhiRenderBuffer *QRhiMetal::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
|
||||
int sampleCount, QRhiRenderBuffer::Flags flags)
|
||||
{
|
||||
@ -655,7 +662,7 @@ void QRhiMetal::enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD
|
||||
{
|
||||
QMetalBuffer *bufD = QRHI_RES(QMetalBuffer, b->u.ubuf.buf);
|
||||
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) {
|
||||
const QRhiCommandBuffer::DynamicOffset &dynOfs(dynamicOffsets[i]);
|
||||
if (dynOfs.first == b->binding) {
|
||||
@ -719,7 +726,7 @@ void QRhiMetal::enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD
|
||||
{
|
||||
QMetalBuffer *bufD = QRHI_RES(QMetalBuffer, b->u.sbuf.buf);
|
||||
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)) {
|
||||
res[0].buffers.feed(b->binding, mtlbuf);
|
||||
res[0].bufferOffsets.feed(b->binding, offset);
|
||||
@ -751,17 +758,17 @@ void QRhiMetal::enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD
|
||||
case 0:
|
||||
[cbD->d->currentRenderPassEncoder setVertexBuffers: bufferBatch.resources.constData()
|
||||
offsets: offsetBatch.resources.constData()
|
||||
withRange: NSMakeRange(bufferBatch.startBinding, bufferBatch.resources.count())];
|
||||
withRange: NSMakeRange(bufferBatch.startBinding, NSUInteger(bufferBatch.resources.count()))];
|
||||
break;
|
||||
case 1:
|
||||
[cbD->d->currentRenderPassEncoder setFragmentBuffers: bufferBatch.resources.constData()
|
||||
offsets: offsetBatch.resources.constData()
|
||||
withRange: NSMakeRange(bufferBatch.startBinding, bufferBatch.resources.count())];
|
||||
withRange: NSMakeRange(bufferBatch.startBinding, NSUInteger(bufferBatch.resources.count()))];
|
||||
break;
|
||||
case 2:
|
||||
[cbD->d->currentComputePassEncoder setBuffers: bufferBatch.resources.constData()
|
||||
offsets: offsetBatch.resources.constData()
|
||||
withRange: NSMakeRange(bufferBatch.startBinding, bufferBatch.resources.count())];
|
||||
withRange: NSMakeRange(bufferBatch.startBinding, NSUInteger(bufferBatch.resources.count()))];
|
||||
break;
|
||||
default:
|
||||
Q_UNREACHABLE();
|
||||
@ -780,15 +787,15 @@ void QRhiMetal::enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD
|
||||
switch (idx) {
|
||||
case 0:
|
||||
[cbD->d->currentRenderPassEncoder setVertexTextures: batch.resources.constData()
|
||||
withRange: NSMakeRange(batch.startBinding, batch.resources.count())];
|
||||
withRange: NSMakeRange(batch.startBinding, NSUInteger(batch.resources.count()))];
|
||||
break;
|
||||
case 1:
|
||||
[cbD->d->currentRenderPassEncoder setFragmentTextures: batch.resources.constData()
|
||||
withRange: NSMakeRange(batch.startBinding, batch.resources.count())];
|
||||
withRange: NSMakeRange(batch.startBinding, NSUInteger(batch.resources.count()))];
|
||||
break;
|
||||
case 2:
|
||||
[cbD->d->currentComputePassEncoder setTextures: batch.resources.constData()
|
||||
withRange: NSMakeRange(batch.startBinding, batch.resources.count())];
|
||||
withRange: NSMakeRange(batch.startBinding, NSUInteger(batch.resources.count()))];
|
||||
break;
|
||||
default:
|
||||
Q_UNREACHABLE();
|
||||
@ -800,15 +807,15 @@ void QRhiMetal::enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD
|
||||
switch (idx) {
|
||||
case 0:
|
||||
[cbD->d->currentRenderPassEncoder setVertexSamplerStates: batch.resources.constData()
|
||||
withRange: NSMakeRange(batch.startBinding, batch.resources.count())];
|
||||
withRange: NSMakeRange(batch.startBinding, NSUInteger(batch.resources.count()))];
|
||||
break;
|
||||
case 1:
|
||||
[cbD->d->currentRenderPassEncoder setFragmentSamplerStates: batch.resources.constData()
|
||||
withRange: NSMakeRange(batch.startBinding, batch.resources.count())];
|
||||
withRange: NSMakeRange(batch.startBinding, NSUInteger(batch.resources.count()))];
|
||||
break;
|
||||
case 2:
|
||||
[cbD->d->currentComputePassEncoder setSamplerStates: batch.resources.constData()
|
||||
withRange: NSMakeRange(batch.startBinding, batch.resources.count())];
|
||||
withRange: NSMakeRange(batch.startBinding, NSUInteger(batch.resources.count()))];
|
||||
break;
|
||||
default:
|
||||
Q_UNREACHABLE();
|
||||
@ -1006,7 +1013,7 @@ void QRhiMetal::setVertexInput(QRhiCommandBuffer *cb,
|
||||
[cbD->d->currentRenderPassEncoder setVertexBuffers:
|
||||
bufferBatch.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;
|
||||
|
||||
MTLViewport vp;
|
||||
vp.originX = x;
|
||||
vp.originY = y;
|
||||
vp.width = w;
|
||||
vp.height = h;
|
||||
vp.znear = viewport.minDepth();
|
||||
vp.zfar = viewport.maxDepth();
|
||||
vp.originX = double(x);
|
||||
vp.originY = double(y);
|
||||
vp.width = double(w);
|
||||
vp.height = double(h);
|
||||
vp.znear = double(viewport.minDepth());
|
||||
vp.zfar = double(viewport.maxDepth());
|
||||
|
||||
[cbD->d->currentRenderPassEncoder setViewport: vp];
|
||||
|
||||
if (!QRHI_RES(QMetalGraphicsPipeline, cbD->currentGraphicsPipeline)->m_flags.testFlag(QRhiGraphicsPipeline::UsesScissor)) {
|
||||
MTLScissorRect s;
|
||||
s.x = x;
|
||||
s.y = y;
|
||||
s.width = w;
|
||||
s.height = h;
|
||||
s.x = NSUInteger(x);
|
||||
s.y = NSUInteger(y);
|
||||
s.width = NSUInteger(w);
|
||||
s.height = NSUInteger(h);
|
||||
[cbD->d->currentRenderPassEncoder setScissorRect: s];
|
||||
}
|
||||
}
|
||||
@ -1099,10 +1106,10 @@ void QRhiMetal::setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor)
|
||||
return;
|
||||
|
||||
MTLScissorRect s;
|
||||
s.x = x;
|
||||
s.y = y;
|
||||
s.width = w;
|
||||
s.height = h;
|
||||
s.x = NSUInteger(x);
|
||||
s.y = NSUInteger(y);
|
||||
s.width = NSUInteger(w);
|
||||
s.height = NSUInteger(h);
|
||||
|
||||
[cbD->d->currentRenderPassEncoder setScissorRect: s];
|
||||
}
|
||||
@ -1112,7 +1119,8 @@ void QRhiMetal::setBlendConstants(QRhiCommandBuffer *cb, const QColor &c)
|
||||
QMetalCommandBuffer *cbD = QRHI_RES(QMetalCommandBuffer, cb);
|
||||
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)
|
||||
@ -1144,7 +1152,7 @@ void QRhiMetal::drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount,
|
||||
return;
|
||||
|
||||
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);
|
||||
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(),
|
||||
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].storeAction = MTLStoreActionStore;
|
||||
rp.colorAttachments[i].clearColor = c;
|
||||
@ -1413,7 +1421,7 @@ MTLRenderPassDescriptor *QRhiMetalData::createDefaultRenderPass(bool hasDepthSte
|
||||
rp.depthAttachment.storeAction = MTLStoreActionDontCare;
|
||||
rp.stencilAttachment.loadAction = MTLLoadActionClear;
|
||||
rp.stencilAttachment.storeAction = MTLStoreActionDontCare;
|
||||
rp.depthAttachment.clearDepth = depthStencilClearValue.depthClearValue();
|
||||
rp.depthAttachment.clearDepth = double(depthStencilClearValue.depthClearValue());
|
||||
rp.stencilAttachment.clearStencil = depthStencilClearValue.stencilClearValue();
|
||||
}
|
||||
|
||||
@ -1426,7 +1434,7 @@ qsizetype QRhiMetal::subresUploadByteSize(const QRhiTextureSubresourceUploadDesc
|
||||
const qsizetype imageSizeBytes = subresDesc.image().isNull() ?
|
||||
subresDesc.data().size() : subresDesc.image().sizeInBytes();
|
||||
if (imageSizeBytes > 0)
|
||||
size += aligned(imageSizeBytes, QRhiMetalData::TEXBUF_ALIGN);
|
||||
size += aligned<qsizetype>(imageSizeBytes, QRhiMetalData::TEXBUF_ALIGN);
|
||||
return size;
|
||||
}
|
||||
|
||||
@ -1454,31 +1462,31 @@ void QRhiMetal::enqueueSubresUpload(QMetalTexture *texD, void *mp, void *blitEnc
|
||||
h = subresDesc.sourceSize().height();
|
||||
}
|
||||
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;
|
||||
// bpl remains set to the original image's row stride
|
||||
} else {
|
||||
img = img.copy(sx, sy, w, h);
|
||||
bpl = img.bytesPerLine();
|
||||
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 {
|
||||
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]
|
||||
sourceOffset: *curOfs + srcOffset
|
||||
sourceBytesPerRow: bpl
|
||||
sourceOffset: NSUInteger(*curOfs + srcOffset)
|
||||
sourceBytesPerRow: NSUInteger(bpl)
|
||||
sourceBytesPerImage: 0
|
||||
sourceSize: MTLSizeMake(w, h, 1)
|
||||
sourceSize: MTLSizeMake(NSUInteger(w), NSUInteger(h), 1)
|
||||
toTexture: texD->d->tex
|
||||
destinationSlice: layer
|
||||
destinationLevel: level
|
||||
destinationOrigin: MTLOriginMake(dp.x(), dp.y(), 0)
|
||||
destinationSlice: NSUInteger(layer)
|
||||
destinationLevel: NSUInteger(level)
|
||||
destinationOrigin: MTLOriginMake(NSUInteger(dp.x()), NSUInteger(dp.y()), 0)
|
||||
options: MTLBlitOptionNone];
|
||||
|
||||
*curOfs += aligned(fullImageSizeBytes, QRhiMetalData::TEXBUF_ALIGN);
|
||||
*curOfs += aligned<qsizetype>(fullImageSizeBytes, QRhiMetalData::TEXBUF_ALIGN);
|
||||
} else if (!rawData.isEmpty() && isCompressedFormat(texD->m_format)) {
|
||||
const QSize subresSize = q->sizeForMipLevel(level, texD->m_pixelSize);
|
||||
const int subresw = subresSize.width();
|
||||
@ -1503,17 +1511,17 @@ void QRhiMetal::enqueueSubresUpload(QMetalTexture *texD, void *mp, void *blitEnc
|
||||
if (dy + h != subresh)
|
||||
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]
|
||||
sourceOffset: *curOfs
|
||||
sourceOffset: NSUInteger(*curOfs)
|
||||
sourceBytesPerRow: bpl
|
||||
sourceBytesPerImage: 0
|
||||
sourceSize: MTLSizeMake(w, h, 1)
|
||||
sourceSize: MTLSizeMake(NSUInteger(w), NSUInteger(h), 1)
|
||||
toTexture: texD->d->tex
|
||||
destinationSlice: layer
|
||||
destinationLevel: level
|
||||
destinationOrigin: MTLOriginMake(dx, dy, 0)
|
||||
destinationSlice: NSUInteger(layer)
|
||||
destinationLevel: NSUInteger(level)
|
||||
destinationOrigin: MTLOriginMake(NSUInteger(dx), NSUInteger(dy), 0)
|
||||
options: MTLBlitOptionNone];
|
||||
|
||||
*curOfs += aligned(rawData.size(), QRhiMetalData::TEXBUF_ALIGN);
|
||||
@ -1532,17 +1540,17 @@ void QRhiMetal::enqueueSubresUpload(QMetalTexture *texD, void *mp, void *blitEnc
|
||||
|
||||
quint32 bpl = 0;
|
||||
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]
|
||||
sourceOffset: *curOfs
|
||||
sourceOffset: NSUInteger(*curOfs)
|
||||
sourceBytesPerRow: bpl
|
||||
sourceBytesPerImage: 0
|
||||
sourceSize: MTLSizeMake(w, h, 1)
|
||||
sourceSize: MTLSizeMake(NSUInteger(w), NSUInteger(h), 1)
|
||||
toTexture: texD->d->tex
|
||||
destinationSlice: layer
|
||||
destinationLevel: level
|
||||
destinationOrigin: MTLOriginMake(dp.x(), dp.y(), 0)
|
||||
destinationSlice: NSUInteger(layer)
|
||||
destinationLevel: NSUInteger(level)
|
||||
destinationOrigin: MTLOriginMake(NSUInteger(dp.x()), NSUInteger(dp.y()), 0)
|
||||
options: MTLBlitOptionNone];
|
||||
|
||||
*curOfs += aligned(rawData.size(), QRhiMetalData::TEXBUF_ALIGN);
|
||||
@ -1596,9 +1604,9 @@ void QRhiMetal::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
|
||||
|
||||
ensureBlit();
|
||||
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];
|
||||
QRHI_PROF_F(newTextureStagingArea(utexD, currentFrameSlot, stagingSize));
|
||||
QRHI_PROF_F(newTextureStagingArea(utexD, currentFrameSlot, quint32(stagingSize)));
|
||||
|
||||
void *mp = [utexD->d->stagingBuf[currentFrameSlot] contents];
|
||||
qsizetype curOfs = 0;
|
||||
@ -1628,14 +1636,14 @@ void QRhiMetal::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
|
||||
|
||||
ensureBlit();
|
||||
[blitEnc copyFromTexture: srcD->d->tex
|
||||
sourceSlice: u.copy.desc.sourceLayer()
|
||||
sourceLevel: u.copy.desc.sourceLevel()
|
||||
sourceOrigin: MTLOriginMake(sp.x(), sp.y(), 0)
|
||||
sourceSize: MTLSizeMake(size.width(), size.height(), 1)
|
||||
sourceSlice: NSUInteger(u.copy.desc.sourceLayer())
|
||||
sourceLevel: NSUInteger(u.copy.desc.sourceLevel())
|
||||
sourceOrigin: MTLOriginMake(NSUInteger(sp.x()), NSUInteger(sp.y()), 0)
|
||||
sourceSize: MTLSizeMake(NSUInteger(size.width()), NSUInteger(size.height()), 1)
|
||||
toTexture: dstD->d->tex
|
||||
destinationSlice: u.copy.desc.destinationLayer()
|
||||
destinationLevel: u.copy.desc.destinationLevel()
|
||||
destinationOrigin: MTLOriginMake(dp.x(), dp.y(), 0)];
|
||||
destinationSlice: NSUInteger(u.copy.desc.destinationLayer())
|
||||
destinationLevel: NSUInteger(u.copy.desc.destinationLevel())
|
||||
destinationOrigin: MTLOriginMake(NSUInteger(dp.x()), NSUInteger(dp.y()), 0)];
|
||||
|
||||
srcD->lastActiveFrameSlot = dstD->lastActiveFrameSlot = currentFrameSlot;
|
||||
} 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);
|
||||
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),
|
||||
aRb.bufSize));
|
||||
|
||||
ensureBlit();
|
||||
[blitEnc copyFromTexture: src
|
||||
sourceSlice: u.read.rb.layer()
|
||||
sourceLevel: u.read.rb.level()
|
||||
sourceSlice: NSUInteger(u.read.rb.layer())
|
||||
sourceLevel: NSUInteger(u.read.rb.level())
|
||||
sourceOrigin: MTLOriginMake(0, 0, 0)
|
||||
sourceSize: MTLSizeMake(srcSize.width(), srcSize.height(), 1)
|
||||
sourceSize: MTLSizeMake(NSUInteger(srcSize.width()), NSUInteger(srcSize.height()), 1)
|
||||
toBuffer: aRb.buf
|
||||
destinationOffset: 0
|
||||
destinationBytesPerRow: bpl
|
||||
@ -1722,14 +1730,14 @@ void QRhiMetal::executeBufferHostWritesForCurrentFrame(QMetalBuffer *bufD)
|
||||
int changeEnd = -1;
|
||||
for (const QRhiResourceUpdateBatchPrivate::DynamicBufferUpdate &u : updates) {
|
||||
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)
|
||||
changeBegin = u.offset;
|
||||
if (changeEnd == -1 || u.offset + u.data.size() > changeEnd)
|
||||
changeEnd = u.offset + u.data.size();
|
||||
}
|
||||
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();
|
||||
}
|
||||
@ -1786,7 +1794,7 @@ void QRhiMetal::beginPass(QRhiCommandBuffer *cb,
|
||||
rtD = rtTex->d;
|
||||
cbD->d->currentPassRpDesc = d->createDefaultRenderPass(rtD->dsAttCount, colorClearValue, depthStencilClearValue, rtD->colorAttCount);
|
||||
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;
|
||||
}
|
||||
if (rtD->dsAttCount && rtTex->m_flags.testFlag(QRhiTextureRenderTarget::PreserveDepthStencilContents)) {
|
||||
@ -1813,15 +1821,15 @@ void QRhiMetal::beginPass(QRhiCommandBuffer *cb,
|
||||
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].slice = rtD->fb.colorAtt[i].layer;
|
||||
cbD->d->currentPassRpDesc.colorAttachments[i].level = rtD->fb.colorAtt[i].level;
|
||||
cbD->d->currentPassRpDesc.colorAttachments[i].slice = NSUInteger(rtD->fb.colorAtt[i].layer);
|
||||
cbD->d->currentPassRpDesc.colorAttachments[i].level = NSUInteger(rtD->fb.colorAtt[i].level);
|
||||
if (rtD->fb.colorAtt[i].resolveTex) {
|
||||
cbD->d->currentPassRpDesc.colorAttachments[i].storeAction = MTLStoreActionMultisampleResolve;
|
||||
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].resolveLevel = rtD->fb.colorAtt[i].resolveLevel;
|
||||
cbD->d->currentPassRpDesc.colorAttachments[i].resolveSlice = NSUInteger(rtD->fb.colorAtt[i].resolveLayer);
|
||||
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);
|
||||
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];
|
||||
}
|
||||
|
||||
@ -1971,12 +1979,12 @@ void QRhiMetal::finishActiveReadbacks(bool forced)
|
||||
if (forced || currentFrameSlot == aRb.activeFrameSlot || aRb.activeFrameSlot < 0) {
|
||||
aRb.result->format = aRb.format;
|
||||
aRb.result->pixelSize = aRb.pixelSize;
|
||||
aRb.result->data.resize(aRb.bufSize);
|
||||
aRb.result->data.resize(int(aRb.bufSize));
|
||||
void *p = [aRb.buf contents];
|
||||
memcpy(aRb.result->data.data(), p, aRb.bufSize);
|
||||
[aRb.buf release];
|
||||
|
||||
QRHI_PROF_F(releaseReadbackBuffer(quint64(quintptr(aRb.buf))));
|
||||
QRHI_PROF_F(releaseReadbackBuffer(qint64(qintptr(aRb.buf))));
|
||||
|
||||
if (aRb.result->completed)
|
||||
completedCallbacks.append(aRb.result->completed);
|
||||
@ -2035,8 +2043,8 @@ bool QMetalBuffer::build()
|
||||
return false;
|
||||
}
|
||||
|
||||
const int nonZeroSize = m_size <= 0 ? 256 : m_size;
|
||||
const int roundedSize = m_usage.testFlag(QRhiBuffer::UniformBuffer) ? aligned(nonZeroSize, 256) : nonZeroSize;
|
||||
const uint nonZeroSize = m_size <= 0 ? 256 : uint(m_size);
|
||||
const uint roundedSize = m_usage.testFlag(QRhiBuffer::UniformBuffer) ? aligned<uint>(nonZeroSize, 256) : nonZeroSize;
|
||||
|
||||
d->managed = false;
|
||||
MTLResourceOptions opts = MTLResourceStorageModeShared;
|
||||
@ -2123,10 +2131,10 @@ bool QMetalRenderBuffer::build()
|
||||
|
||||
MTLTextureDescriptor *desc = [[MTLTextureDescriptor alloc] init];
|
||||
desc.textureType = samples > 1 ? MTLTextureType2DMultisample : MTLTextureType2D;
|
||||
desc.width = m_pixelSize.width();
|
||||
desc.height = m_pixelSize.height();
|
||||
desc.width = NSUInteger(m_pixelSize.width());
|
||||
desc.height = NSUInteger(m_pixelSize.height());
|
||||
if (samples > 1)
|
||||
desc.sampleCount = samples;
|
||||
desc.sampleCount = NSUInteger(samples);
|
||||
desc.resourceOptions = MTLResourceStorageModePrivate;
|
||||
desc.usage = MTLTextureUsageRenderTarget;
|
||||
|
||||
@ -2393,11 +2401,11 @@ bool QMetalTexture::build()
|
||||
else
|
||||
desc.textureType = samples > 1 ? MTLTextureType2DMultisample : MTLTextureType2D;
|
||||
desc.pixelFormat = d->format;
|
||||
desc.width = size.width();
|
||||
desc.height = size.height();
|
||||
desc.mipmapLevelCount = mipLevelCount;
|
||||
desc.width = NSUInteger(size.width());
|
||||
desc.height = NSUInteger(size.height());
|
||||
desc.mipmapLevelCount = NSUInteger(mipLevelCount);
|
||||
if (samples > 1)
|
||||
desc.sampleCount = samples;
|
||||
desc.sampleCount = NSUInteger(samples);
|
||||
desc.resourceOptions = MTLResourceStorageModePrivate;
|
||||
desc.storageMode = MTLStorageModePrivate;
|
||||
desc.usage = MTLTextureUsageShaderRead;
|
||||
@ -2463,7 +2471,7 @@ id<MTLTexture> QMetalTextureData::viewForLevel(int level)
|
||||
const MTLTextureType type = [tex textureType];
|
||||
const bool isCube = q->m_flags.testFlag(QRhiTexture::CubeMap);
|
||||
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;
|
||||
return view;
|
||||
@ -2673,13 +2681,13 @@ QRhiRenderPassDescriptor *QMetalTextureRenderTarget::newCompatibleRenderPassDesc
|
||||
for (int i = 0, ie = colorAttachments.count(); i != ie; ++i) {
|
||||
QMetalTexture *texD = QRHI_RES(QMetalTexture, colorAttachments[i].texture());
|
||||
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())
|
||||
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())
|
||||
rpD->dsFormat = QRHI_RES(QMetalRenderBuffer, m_desc.depthStencilBuffer())->d->format;
|
||||
rpD->dsFormat = int(QRHI_RES(QMetalRenderBuffer, m_desc.depthStencilBuffer())->d->format);
|
||||
|
||||
return rpD;
|
||||
}
|
||||
@ -3079,7 +3087,7 @@ id<MTLLibrary> QRhiMetalData::createMetalLib(const QShader &shader, QShader::Var
|
||||
QShaderCode mtllib = shader.shader({ QShader::MetalLibShader, 12, shaderVariant });
|
||||
if (!mtllib.shader().isEmpty()) {
|
||||
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_DATA_DESTRUCTOR_DEFAULT);
|
||||
NSError *err = nil;
|
||||
@ -3139,19 +3147,19 @@ bool QMetalGraphicsPipeline::build()
|
||||
MTLVertexDescriptor *inputLayout = [MTLVertexDescriptor vertexDescriptor];
|
||||
const QVector<QRhiVertexInputAttribute> attributes = m_vertexInputLayout.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].offset = attribute.offset();
|
||||
inputLayout.attributes[loc].bufferIndex = firstVertexBinding + attribute.binding();
|
||||
inputLayout.attributes[loc].offset = NSUInteger(attribute.offset());
|
||||
inputLayout.attributes[loc].bufferIndex = NSUInteger(firstVertexBinding + attribute.binding());
|
||||
}
|
||||
const QVector<QRhiVertexInputBinding> bindings = m_vertexInputLayout.bindings();
|
||||
for (int i = 0, ie = bindings.count(); i != ie; ++i) {
|
||||
const QRhiVertexInputBinding &binding(bindings[i]);
|
||||
const int layoutIdx = firstVertexBinding + i;
|
||||
const uint layoutIdx = uint(firstVertexBinding + i);
|
||||
inputLayout.layouts[layoutIdx].stepFunction =
|
||||
binding.classification() == QRhiVertexInputBinding::PerInstance
|
||||
? MTLVertexStepFunctionPerInstance : MTLVertexStepFunctionPerVertex;
|
||||
inputLayout.layouts[layoutIdx].stepRate = binding.instanceStepRate();
|
||||
inputLayout.layouts[layoutIdx].stepRate = NSUInteger(binding.instanceStepRate());
|
||||
inputLayout.layouts[layoutIdx].stride = binding.stride();
|
||||
}
|
||||
|
||||
@ -3239,8 +3247,8 @@ bool QMetalGraphicsPipeline::build()
|
||||
Q_ASSERT(m_targetBlends.count() == rpD->colorAttachmentCount
|
||||
|| (m_targetBlends.isEmpty() && rpD->colorAttachmentCount == 1));
|
||||
|
||||
for (int i = 0, ie = m_targetBlends.count(); i != ie; ++i) {
|
||||
const QRhiGraphicsPipeline::TargetBlend &b(m_targetBlends[i]);
|
||||
for (uint i = 0, ie = uint(m_targetBlends.count()); i != ie; ++i) {
|
||||
const QRhiGraphicsPipeline::TargetBlend &b(m_targetBlends[int(i)]);
|
||||
rpDesc.colorAttachments[i].pixelFormat = MTLPixelFormat(rpD->colorFormat[i]);
|
||||
rpDesc.colorAttachments[i].blendingEnabled = b.enable;
|
||||
rpDesc.colorAttachments[i].sourceRGBBlendFactor = toMetalBlendFactor(b.srcColor);
|
||||
@ -3262,7 +3270,7 @@ bool QMetalGraphicsPipeline::build()
|
||||
rpDesc.stencilAttachmentPixelFormat = fmt;
|
||||
}
|
||||
|
||||
rpDesc.sampleCount = rhiD->effectiveSampleCount(m_sampleCount);
|
||||
rpDesc.sampleCount = NSUInteger(rhiD->effectiveSampleCount(m_sampleCount));
|
||||
|
||||
NSError *err = nil;
|
||||
d->ps = [rhiD->d->dev newRenderPipelineStateWithDescriptor: rpDesc error: &err];
|
||||
@ -3517,7 +3525,7 @@ QSize QMetalSwapChain::surfacePixelSize()
|
||||
CAMetalLayer *layer = (CAMetalLayer *) [v layer];
|
||||
if (layer) {
|
||||
CGSize size = [layer drawableSize];
|
||||
return QSize(size.width, size.height);
|
||||
return QSize(int(size.width), int(size.height));
|
||||
}
|
||||
}
|
||||
return QSize();
|
||||
@ -3532,7 +3540,7 @@ QRhiRenderPassDescriptor *QMetalSwapChain::newCompatibleRenderPassDescriptor()
|
||||
rpD->colorAttachmentCount = 1;
|
||||
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
|
||||
rpD->dsFormat = rhiD->d->dev.depth24Stencil8PixelFormatSupported
|
||||
@ -3589,6 +3597,18 @@ bool QMetalSwapChain::buildOrResize()
|
||||
}
|
||||
#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();
|
||||
pixelSize = m_currentPixelSize;
|
||||
|
||||
@ -3616,7 +3636,7 @@ bool QMetalSwapChain::buildOrResize()
|
||||
}
|
||||
|
||||
rtWrapper.d->pixelSize = pixelSize;
|
||||
rtWrapper.d->dpr = window->devicePixelRatio();
|
||||
rtWrapper.d->dpr = float(window->devicePixelRatio());
|
||||
rtWrapper.d->sampleCount = samples;
|
||||
rtWrapper.d->colorAttCount = 1;
|
||||
rtWrapper.d->dsAttCount = ds ? 1 : 0;
|
||||
@ -3627,9 +3647,9 @@ bool QMetalSwapChain::buildOrResize()
|
||||
MTLTextureDescriptor *desc = [[MTLTextureDescriptor alloc] init];
|
||||
desc.textureType = MTLTextureType2DMultisample;
|
||||
desc.pixelFormat = d->colorFormat;
|
||||
desc.width = pixelSize.width();
|
||||
desc.height = pixelSize.height();
|
||||
desc.sampleCount = samples;
|
||||
desc.width = NSUInteger(pixelSize.width());
|
||||
desc.height = NSUInteger(pixelSize.height());
|
||||
desc.sampleCount = NSUInteger(samples);
|
||||
desc.resourceOptions = MTLResourceStorageModePrivate;
|
||||
desc.storageMode = MTLStorageModePrivate;
|
||||
desc.usage = MTLTextureUsageRenderTarget;
|
||||
|
@ -416,8 +416,9 @@ public:
|
||||
int resourceLimit(QRhi::ResourceLimit limit) const override;
|
||||
const QRhiNativeHandles *nativeHandles() override;
|
||||
void sendVMemStatsToProfiler() override;
|
||||
void makeThreadLocalNativeContextCurrent() override;
|
||||
bool makeThreadLocalNativeContextCurrent() override;
|
||||
void releaseCachedResources() override;
|
||||
bool isDeviceLost() const override;
|
||||
|
||||
void executeDeferredReleases(bool forced = false);
|
||||
void finishActiveReadbacks(bool forced = false);
|
||||
|
@ -169,9 +169,10 @@ void QRhiNull::sendVMemStatsToProfiler()
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
void QRhiNull::makeThreadLocalNativeContextCurrent()
|
||||
bool QRhiNull::makeThreadLocalNativeContextCurrent()
|
||||
{
|
||||
// nothing to do here
|
||||
// not applicable
|
||||
return false;
|
||||
}
|
||||
|
||||
void QRhiNull::releaseCachedResources()
|
||||
@ -179,6 +180,11 @@ void QRhiNull::releaseCachedResources()
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
bool QRhiNull::isDeviceLost() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QRhiRenderBuffer *QRhiNull::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
|
||||
int sampleCount, QRhiRenderBuffer::Flags flags)
|
||||
{
|
||||
|
@ -282,8 +282,9 @@ public:
|
||||
int resourceLimit(QRhi::ResourceLimit limit) const override;
|
||||
const QRhiNativeHandles *nativeHandles() override;
|
||||
void sendVMemStatsToProfiler() override;
|
||||
void makeThreadLocalNativeContextCurrent() override;
|
||||
bool makeThreadLocalNativeContextCurrent() override;
|
||||
void releaseCachedResources() override;
|
||||
bool isDeviceLost() const override;
|
||||
|
||||
QRhiNullNativeHandles nativeHandlesStruct;
|
||||
QRhiSwapChain *currentSwapChain = nullptr;
|
||||
|
@ -319,7 +319,7 @@ void QRhiProfilerPrivate::writeFloat(const char *key, float f)
|
||||
Q_ASSERT(key[0] == 'F');
|
||||
buf.append(key);
|
||||
buf.append(',');
|
||||
buf.append(QByteArray::number(f));
|
||||
buf.append(QByteArray::number(double(f)));
|
||||
buf.append(',');
|
||||
}
|
||||
|
||||
@ -385,7 +385,7 @@ void QRhiProfilerPrivate::newRenderBuffer(QRhiRenderBuffer *rb, bool transientBa
|
||||
const QRhiTexture::Format assumedFormat = type == QRhiRenderBuffer::DepthStencil ? QRhiTexture::D32F : QRhiTexture::RGBA8;
|
||||
quint32 byteSize = rhiDWhenEnabled->approxByteSizeForTexture(assumedFormat, sz, 1, 1);
|
||||
if (sampleCount > 1)
|
||||
byteSize *= sampleCount;
|
||||
byteSize *= uint(sampleCount);
|
||||
|
||||
startEntry(QRhiProfiler::NewRenderBuffer, ts.elapsed(), rb);
|
||||
writeInt("type", type);
|
||||
@ -416,7 +416,7 @@ void QRhiProfilerPrivate::newTexture(QRhiTexture *tex, bool owns, int mipCount,
|
||||
const QSize sz = tex->pixelSize();
|
||||
quint32 byteSize = rhiDWhenEnabled->approxByteSizeForTexture(format, sz, mipCount, layerCount);
|
||||
if (sampleCount > 1)
|
||||
byteSize *= sampleCount;
|
||||
byteSize *= uint(sampleCount);
|
||||
|
||||
startEntry(QRhiProfiler::NewTexture, ts.elapsed(), tex);
|
||||
writeInt("width", sz.width());
|
||||
@ -467,7 +467,7 @@ void QRhiProfilerPrivate::resizeSwapChain(QRhiSwapChain *sc, int bufferCount, in
|
||||
|
||||
const QSize sz = sc->currentPixelSize();
|
||||
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);
|
||||
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)
|
||||
return;
|
||||
@ -580,7 +580,7 @@ void QRhiProfilerPrivate::newReadbackBuffer(quint64 id, QRhiResource *src, quint
|
||||
endEntry();
|
||||
}
|
||||
|
||||
void QRhiProfilerPrivate::releaseReadbackBuffer(quint64 id)
|
||||
void QRhiProfilerPrivate::releaseReadbackBuffer(qint64 id)
|
||||
{
|
||||
if (!outputDevice)
|
||||
return;
|
||||
@ -590,7 +590,7 @@ void QRhiProfilerPrivate::releaseReadbackBuffer(quint64 id)
|
||||
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)
|
||||
return;
|
||||
|
@ -79,10 +79,10 @@ public:
|
||||
void endSwapChainFrame(QRhiSwapChain *sc, int frameCount);
|
||||
void swapChainFrameGpuTime(QRhiSwapChain *sc, float gpuTimeMs);
|
||||
|
||||
void newReadbackBuffer(quint64 id, QRhiResource *src, quint32 size);
|
||||
void releaseReadbackBuffer(quint64 id);
|
||||
void newReadbackBuffer(qint64 id, QRhiResource *src, quint32 size);
|
||||
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 writeInt(const char *key, qint64 v);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -711,8 +711,9 @@ public:
|
||||
int resourceLimit(QRhi::ResourceLimit limit) const override;
|
||||
const QRhiNativeHandles *nativeHandles() override;
|
||||
void sendVMemStatsToProfiler() override;
|
||||
void makeThreadLocalNativeContextCurrent() override;
|
||||
bool makeThreadLocalNativeContextCurrent() override;
|
||||
void releaseCachedResources() override;
|
||||
bool isDeviceLost() const override;
|
||||
|
||||
VkResult createDescriptorPool(VkDescriptorPool *pool);
|
||||
bool allocateDescriptorSet(VkDescriptorSetAllocateInfo *allocInfo, VkDescriptorSet *result, int *resultPoolIndex);
|
||||
@ -804,6 +805,7 @@ public:
|
||||
VkDeviceSize ubufAlign;
|
||||
VkDeviceSize texbufAlign;
|
||||
bool hasWideLines = false;
|
||||
bool deviceLost = false;
|
||||
|
||||
bool debugMarkersAvailable = false;
|
||||
bool vertexAttribDivisorAvailable = false;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user