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 "mainwindow.h"
|
||||||
#include "encodingdialog.h"
|
#include "encodingdialog.h"
|
||||||
#include "previewform.h"
|
#include "previewform.h"
|
||||||
|
|
||||||
|
#include <QAction>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QDesktopWidget>
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QMenuBar>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QPlainTextEdit>
|
||||||
|
#include <QRegularExpression>
|
||||||
|
#include <QTextCodec>
|
||||||
|
#include <QTextStream>
|
||||||
|
|
||||||
MainWindow::MainWindow()
|
MainWindow::MainWindow()
|
||||||
{
|
{
|
||||||
textEdit = new QPlainTextEdit;
|
textEdit = new QPlainTextEdit;
|
||||||
@ -146,14 +155,14 @@ void MainWindow::findCodecs()
|
|||||||
QTextCodec *codec = QTextCodec::codecForMib(mib);
|
QTextCodec *codec = QTextCodec::codecForMib(mib);
|
||||||
|
|
||||||
QString sortKey = codec->name().toUpper();
|
QString sortKey = codec->name().toUpper();
|
||||||
int rank;
|
char rank;
|
||||||
|
|
||||||
if (sortKey.startsWith(QLatin1String("UTF-8"))) {
|
if (sortKey.startsWith(QLatin1String("UTF-8"))) {
|
||||||
rank = 1;
|
rank = 1;
|
||||||
} else if (sortKey.startsWith(QLatin1String("UTF-16"))) {
|
} else if (sortKey.startsWith(QLatin1String("UTF-16"))) {
|
||||||
rank = 2;
|
rank = 2;
|
||||||
} else if ((match = iso8859RegExp.match(sortKey)).hasMatch()) {
|
} else if ((match = iso8859RegExp.match(sortKey)).hasMatch()) {
|
||||||
if (match.captured(1).size() == 1)
|
if (match.capturedRef(1).size() == 1)
|
||||||
rank = 3;
|
rank = 3;
|
||||||
else
|
else
|
||||||
rank = 4;
|
rank = 4;
|
||||||
@ -164,7 +173,8 @@ void MainWindow::findCodecs()
|
|||||||
|
|
||||||
codecMap.insert(sortKey, codec);
|
codecMap.insert(sortKey, codec);
|
||||||
}
|
}
|
||||||
codecs = codecMap.values();
|
for (const auto &codec : qAsConst(codecMap))
|
||||||
|
codecs += codec;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::createMenus()
|
void MainWindow::createMenus()
|
||||||
|
@ -51,7 +51,7 @@
|
|||||||
#ifndef MAINWINDOW_H
|
#ifndef MAINWINDOW_H
|
||||||
#define MAINWINDOW_H
|
#define MAINWINDOW_H
|
||||||
|
|
||||||
#include <QList>
|
#include <QVector>
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
@ -81,10 +81,10 @@ private:
|
|||||||
void findCodecs();
|
void findCodecs();
|
||||||
void createMenus();
|
void createMenus();
|
||||||
|
|
||||||
QList<QAction *> saveAsActs;
|
QVector<QAction *> saveAsActs;
|
||||||
QPlainTextEdit *textEdit;
|
QPlainTextEdit *textEdit;
|
||||||
PreviewForm *previewForm;
|
PreviewForm *previewForm;
|
||||||
QList<QTextCodec *> codecs;
|
QVector<QTextCodec *> codecs;
|
||||||
EncodingDialog *m_encodingDialog = nullptr;
|
EncodingDialog *m_encodingDialog = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -48,10 +48,19 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <QtWidgets>
|
|
||||||
|
|
||||||
#include "previewform.h"
|
#include "previewform.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QDesktopWidget>
|
||||||
|
#include <QDialogButtonBox>
|
||||||
|
#include <QGridLayout>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QPlainTextEdit>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QTextCodec>
|
||||||
|
#include <QTextStream>
|
||||||
|
|
||||||
// Helpers for creating hex dumps
|
// Helpers for creating hex dumps
|
||||||
static void indent(QTextStream &str, int indent)
|
static void indent(QTextStream &str, int indent)
|
||||||
{
|
{
|
||||||
@ -83,8 +92,7 @@ static void formatHex(QTextStream &str, const QByteArray &data)
|
|||||||
|
|
||||||
static void formatPrintableCharacters(QTextStream &str, const QByteArray &data)
|
static void formatPrintableCharacters(QTextStream &str, const QByteArray &data)
|
||||||
{
|
{
|
||||||
for (int i = 0, size = data.size(); i < size; ++i) {
|
for (const char c : data) {
|
||||||
const char c = data.at(i);
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '\0':
|
case '\0':
|
||||||
str << "\\0";
|
str << "\\0";
|
||||||
@ -179,7 +187,7 @@ PreviewForm::PreviewForm(QWidget *parent)
|
|||||||
resize(screenGeometry.width() * 2 / 5, screenGeometry.height() / 2);
|
resize(screenGeometry.width() * 2 / 5, screenGeometry.height() / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PreviewForm::setCodecList(const QList<QTextCodec *> &list)
|
void PreviewForm::setCodecList(const QVector<QTextCodec *> &list)
|
||||||
{
|
{
|
||||||
encodingComboBox->clear();
|
encodingComboBox->clear();
|
||||||
for (const QTextCodec *codec : list) {
|
for (const QTextCodec *codec : list) {
|
||||||
@ -226,10 +234,10 @@ void PreviewForm::updateTextEdit()
|
|||||||
statusLabel->setText(message);
|
statusLabel->setText(message);
|
||||||
statusLabel->setStyleSheet(QStringLiteral("background-color: \"red\";"));
|
statusLabel->setStyleSheet(QStringLiteral("background-color: \"red\";"));
|
||||||
} else if (state.invalidChars) {
|
} else if (state.invalidChars) {
|
||||||
statusLabel->setText(tr("%1: %n invalid characters", 0, state.invalidChars).arg(name));
|
statusLabel->setText(tr("%1: %n invalid characters", nullptr, state.invalidChars).arg(name));
|
||||||
statusLabel->setStyleSheet(QStringLiteral("background-color: \"yellow\";"));
|
statusLabel->setStyleSheet(QStringLiteral("background-color: \"yellow\";"));
|
||||||
} else {
|
} else {
|
||||||
statusLabel->setText(tr("%1: %n bytes converted", 0, encodedData.size()).arg(name));
|
statusLabel->setText(tr("%1: %n bytes converted", nullptr, encodedData.size()).arg(name));
|
||||||
statusLabel->setStyleSheet(QString());
|
statusLabel->setStyleSheet(QString());
|
||||||
}
|
}
|
||||||
if (success)
|
if (success)
|
||||||
|
@ -52,7 +52,7 @@
|
|||||||
#define PREVIEWFORM_H
|
#define PREVIEWFORM_H
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QList>
|
#include <QVector>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
class QComboBox;
|
class QComboBox;
|
||||||
@ -71,7 +71,7 @@ class PreviewForm : public QDialog
|
|||||||
public:
|
public:
|
||||||
explicit PreviewForm(QWidget *parent = nullptr);
|
explicit PreviewForm(QWidget *parent = nullptr);
|
||||||
|
|
||||||
void setCodecList(const QList<QTextCodec *> &list);
|
void setCodecList(const QVector<QTextCodec *> &list);
|
||||||
void setEncodedData(const QByteArray &data);
|
void setEncodedData(const QByteArray &data);
|
||||||
QString decodedString() const { return decodedStr; }
|
QString decodedString() const { return decodedStr; }
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@
|
|||||||
class FileSystemModel : public QFileSystemModel
|
class FileSystemModel : public QFileSystemModel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FileSystemModel(QObject *parent = 0);
|
FileSystemModel(QObject *parent = nullptr);
|
||||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
};
|
};
|
||||||
//! [0]
|
//! [0]
|
||||||
|
@ -48,13 +48,28 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <QtWidgets>
|
|
||||||
#include "fsmodel.h"
|
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
#include "fsmodel.h"
|
||||||
|
|
||||||
|
#include <QAction>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QCompleter>
|
||||||
|
#include <QGridLayout>
|
||||||
|
#include <QHeaderView>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QMenuBar>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QSpinBox>
|
||||||
|
#include <QStandardItemModel>
|
||||||
|
#include <QStringListModel>
|
||||||
|
#include <QTreeView>
|
||||||
|
|
||||||
//! [0]
|
//! [0]
|
||||||
MainWindow::MainWindow(QWidget *parent)
|
MainWindow::MainWindow(QWidget *parent)
|
||||||
: QMainWindow(parent), completer(0), lineEdit(0)
|
: QMainWindow(parent)
|
||||||
{
|
{
|
||||||
createMenu();
|
createMenu();
|
||||||
|
|
||||||
@ -64,8 +79,8 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
modelLabel->setText(tr("Model"));
|
modelLabel->setText(tr("Model"));
|
||||||
|
|
||||||
modelCombo = new QComboBox;
|
modelCombo = new QComboBox;
|
||||||
modelCombo->addItem(tr("QFileSytemModel"));
|
modelCombo->addItem(tr("QFileSystemModel"));
|
||||||
modelCombo->addItem(tr("QFileSytemModel that shows full path"));
|
modelCombo->addItem(tr("QFileSystemModel that shows full path"));
|
||||||
modelCombo->addItem(tr("Country list"));
|
modelCombo->addItem(tr("Country list"));
|
||||||
modelCombo->addItem(tr("Word list"));
|
modelCombo->addItem(tr("Word list"));
|
||||||
modelCombo->setCurrentIndex(0);
|
modelCombo->setCurrentIndex(0);
|
||||||
@ -144,17 +159,17 @@ void MainWindow::createMenu()
|
|||||||
connect(aboutAct, &QAction::triggered, this, &MainWindow::about);
|
connect(aboutAct, &QAction::triggered, this, &MainWindow::about);
|
||||||
connect(aboutQtAct, &QAction::triggered, qApp, &QApplication::aboutQt);
|
connect(aboutQtAct, &QAction::triggered, qApp, &QApplication::aboutQt);
|
||||||
|
|
||||||
QMenu* fileMenu = menuBar()->addMenu(tr("File"));
|
QMenu *fileMenu = menuBar()->addMenu(tr("File"));
|
||||||
fileMenu->addAction(exitAction);
|
fileMenu->addAction(exitAction);
|
||||||
|
|
||||||
QMenu* helpMenu = menuBar()->addMenu(tr("About"));
|
QMenu *helpMenu = menuBar()->addMenu(tr("About"));
|
||||||
helpMenu->addAction(aboutAct);
|
helpMenu->addAction(aboutAct);
|
||||||
helpMenu->addAction(aboutQtAct);
|
helpMenu->addAction(aboutQtAct);
|
||||||
}
|
}
|
||||||
//! [4]
|
//! [4]
|
||||||
|
|
||||||
//! [5]
|
//! [5]
|
||||||
QAbstractItemModel *MainWindow::modelFromFile(const QString& fileName)
|
QAbstractItemModel *MainWindow::modelFromFile(const QString &fileName)
|
||||||
{
|
{
|
||||||
QFile file(fileName);
|
QFile file(fileName);
|
||||||
if (!file.open(QFile::ReadOnly))
|
if (!file.open(QFile::ReadOnly))
|
||||||
@ -170,7 +185,7 @@ QAbstractItemModel *MainWindow::modelFromFile(const QString& fileName)
|
|||||||
while (!file.atEnd()) {
|
while (!file.atEnd()) {
|
||||||
QByteArray line = file.readLine();
|
QByteArray line = file.readLine();
|
||||||
if (!line.isEmpty())
|
if (!line.isEmpty())
|
||||||
words << line.trimmed();
|
words << QString::fromUtf8(line.trimmed());
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef QT_NO_CURSOR
|
#ifndef QT_NO_CURSOR
|
||||||
@ -191,8 +206,8 @@ QAbstractItemModel *MainWindow::modelFromFile(const QString& fileName)
|
|||||||
for (int i = 0; i < words.count(); ++i) {
|
for (int i = 0; i < words.count(); ++i) {
|
||||||
QModelIndex countryIdx = m->index(i, 0);
|
QModelIndex countryIdx = m->index(i, 0);
|
||||||
QModelIndex symbolIdx = m->index(i, 1);
|
QModelIndex symbolIdx = m->index(i, 1);
|
||||||
QString country = words[i].mid(0, words[i].length() - 2).trimmed();
|
QString country = words.at(i).mid(0, words[i].length() - 2).trimmed();
|
||||||
QString symbol = words[i].right(2);
|
QString symbol = words.at(i).right(2);
|
||||||
m->setData(countryIdx, country);
|
m->setData(countryIdx, country);
|
||||||
m->setData(symbolIdx, symbol);
|
m->setData(symbolIdx, symbol);
|
||||||
}
|
}
|
||||||
@ -233,7 +248,7 @@ void MainWindow::changeModel()
|
|||||||
case 0:
|
case 0:
|
||||||
{ // Unsorted QFileSystemModel
|
{ // Unsorted QFileSystemModel
|
||||||
QFileSystemModel *fsModel = new QFileSystemModel(completer);
|
QFileSystemModel *fsModel = new QFileSystemModel(completer);
|
||||||
fsModel->setRootPath("");
|
fsModel->setRootPath(QString());
|
||||||
completer->setModel(fsModel);
|
completer->setModel(fsModel);
|
||||||
contentsLabel->setText(tr("Enter file path"));
|
contentsLabel->setText(tr("Enter file path"));
|
||||||
}
|
}
|
||||||
@ -243,7 +258,7 @@ void MainWindow::changeModel()
|
|||||||
{ // FileSystemModel that shows full paths
|
{ // FileSystemModel that shows full paths
|
||||||
FileSystemModel *fsModel = new FileSystemModel(completer);
|
FileSystemModel *fsModel = new FileSystemModel(completer);
|
||||||
completer->setModel(fsModel);
|
completer->setModel(fsModel);
|
||||||
fsModel->setRootPath("");
|
fsModel->setRootPath(QString());
|
||||||
contentsLabel->setText(tr("Enter file path"));
|
contentsLabel->setText(tr("Enter file path"));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -59,7 +59,6 @@ class QComboBox;
|
|||||||
class QCompleter;
|
class QCompleter;
|
||||||
class QLabel;
|
class QLabel;
|
||||||
class QLineEdit;
|
class QLineEdit;
|
||||||
class QProgressBar;
|
|
||||||
class QCheckBox;
|
class QCheckBox;
|
||||||
class QSpinBox;
|
class QSpinBox;
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
@ -70,7 +69,7 @@ class MainWindow : public QMainWindow
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MainWindow(QWidget *parent = 0);
|
MainWindow(QWidget *parent = nullptr);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void about();
|
void about();
|
||||||
@ -83,16 +82,16 @@ private slots:
|
|||||||
//! [1]
|
//! [1]
|
||||||
private:
|
private:
|
||||||
void createMenu();
|
void createMenu();
|
||||||
QAbstractItemModel *modelFromFile(const QString& fileName);
|
QAbstractItemModel *modelFromFile(const QString &fileName);
|
||||||
|
|
||||||
QComboBox *caseCombo;
|
QComboBox *caseCombo = nullptr;
|
||||||
QComboBox *modeCombo;
|
QComboBox *modeCombo = nullptr;
|
||||||
QComboBox *modelCombo;
|
QComboBox *modelCombo = nullptr;
|
||||||
QSpinBox *maxVisibleSpinBox;
|
QSpinBox *maxVisibleSpinBox = nullptr;
|
||||||
QCheckBox *wrapCheckBox;
|
QCheckBox *wrapCheckBox = nullptr;
|
||||||
QCompleter *completer;
|
QCompleter *completer = nullptr;
|
||||||
QLabel *contentsLabel;
|
QLabel *contentsLabel = nullptr;
|
||||||
QLineEdit *lineEdit;
|
QLineEdit *lineEdit = nullptr;
|
||||||
};
|
};
|
||||||
//! [1]
|
//! [1]
|
||||||
|
|
||||||
|
@ -48,13 +48,20 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <QtWidgets>
|
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "textedit.h"
|
#include "textedit.h"
|
||||||
|
|
||||||
|
#include <QAction>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QCompleter>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QMenuBar>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QStringListModel>
|
||||||
|
|
||||||
//! [0]
|
//! [0]
|
||||||
MainWindow::MainWindow(QWidget *parent)
|
MainWindow::MainWindow(QWidget *parent)
|
||||||
: QMainWindow(parent), completer(0)
|
: QMainWindow(parent)
|
||||||
{
|
{
|
||||||
createMenu();
|
createMenu();
|
||||||
|
|
||||||
@ -83,10 +90,10 @@ void MainWindow::createMenu()
|
|||||||
connect(aboutAct, &QAction::triggered, this, &MainWindow::about);
|
connect(aboutAct, &QAction::triggered, this, &MainWindow::about);
|
||||||
connect(aboutQtAct, &QAction::triggered, qApp, &QApplication::aboutQt);
|
connect(aboutQtAct, &QAction::triggered, qApp, &QApplication::aboutQt);
|
||||||
|
|
||||||
QMenu* fileMenu = menuBar()->addMenu(tr("File"));
|
QMenu *fileMenu = menuBar()->addMenu(tr("File"));
|
||||||
fileMenu->addAction(exitAction);
|
fileMenu->addAction(exitAction);
|
||||||
|
|
||||||
QMenu* helpMenu = menuBar()->addMenu(tr("About"));
|
QMenu *helpMenu = menuBar()->addMenu(tr("About"));
|
||||||
helpMenu->addAction(aboutAct);
|
helpMenu->addAction(aboutAct);
|
||||||
helpMenu->addAction(aboutQtAct);
|
helpMenu->addAction(aboutQtAct);
|
||||||
}
|
}
|
||||||
@ -107,7 +114,7 @@ QAbstractItemModel *MainWindow::modelFromFile(const QString& fileName)
|
|||||||
while (!file.atEnd()) {
|
while (!file.atEnd()) {
|
||||||
QByteArray line = file.readLine();
|
QByteArray line = file.readLine();
|
||||||
if (!line.isEmpty())
|
if (!line.isEmpty())
|
||||||
words << line.trimmed();
|
words << QString::fromUtf8(line.trimmed());
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef QT_NO_CURSOR
|
#ifndef QT_NO_CURSOR
|
||||||
|
@ -55,11 +55,7 @@
|
|||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
class QAbstractItemModel;
|
class QAbstractItemModel;
|
||||||
class QComboBox;
|
|
||||||
class QCompleter;
|
class QCompleter;
|
||||||
class QLabel;
|
|
||||||
class QLineEdit;
|
|
||||||
class QProgressBar;
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
class TextEdit;
|
class TextEdit;
|
||||||
|
|
||||||
@ -69,7 +65,7 @@ class MainWindow : public QMainWindow
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MainWindow(QWidget *parent = 0);
|
MainWindow(QWidget *parent = nullptr);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void about();
|
void about();
|
||||||
@ -78,7 +74,7 @@ private:
|
|||||||
void createMenu();
|
void createMenu();
|
||||||
QAbstractItemModel *modelFromFile(const QString& fileName);
|
QAbstractItemModel *modelFromFile(const QString& fileName);
|
||||||
|
|
||||||
QCompleter *completer;
|
QCompleter *completer = nullptr;
|
||||||
TextEdit *completingTextEdit;
|
TextEdit *completingTextEdit;
|
||||||
};
|
};
|
||||||
//! [0]
|
//! [0]
|
||||||
|
@ -60,7 +60,7 @@
|
|||||||
|
|
||||||
//! [0]
|
//! [0]
|
||||||
TextEdit::TextEdit(QWidget *parent)
|
TextEdit::TextEdit(QWidget *parent)
|
||||||
: QTextEdit(parent), c(0)
|
: QTextEdit(parent)
|
||||||
{
|
{
|
||||||
setPlainText(tr("This TextEdit provides autocompletions for words that have more than"
|
setPlainText(tr("This TextEdit provides autocompletions for words that have more than"
|
||||||
" 3 characters. You can trigger autocompletion using ") +
|
" 3 characters. You can trigger autocompletion using ") +
|
||||||
@ -78,7 +78,7 @@ TextEdit::~TextEdit()
|
|||||||
void TextEdit::setCompleter(QCompleter *completer)
|
void TextEdit::setCompleter(QCompleter *completer)
|
||||||
{
|
{
|
||||||
if (c)
|
if (c)
|
||||||
QObject::disconnect(c, 0, this, 0);
|
c->disconnect(this);
|
||||||
|
|
||||||
c = completer;
|
c = completer;
|
||||||
|
|
||||||
@ -101,7 +101,7 @@ QCompleter *TextEdit::completer() const
|
|||||||
//! [3]
|
//! [3]
|
||||||
|
|
||||||
//! [4]
|
//! [4]
|
||||||
void TextEdit::insertCompletion(const QString& completion)
|
void TextEdit::insertCompletion(const QString &completion)
|
||||||
{
|
{
|
||||||
if (c->widget() != this)
|
if (c->widget() != this)
|
||||||
return;
|
return;
|
||||||
@ -150,18 +150,19 @@ void TextEdit::keyPressEvent(QKeyEvent *e)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isShortcut = ((e->modifiers() & Qt::ControlModifier) && e->key() == Qt::Key_E); // CTRL+E
|
const bool isShortcut = (e->modifiers().testFlag(Qt::ControlModifier) && e->key() == Qt::Key_E); // CTRL+E
|
||||||
if (!c || !isShortcut) // do not process the shortcut when we have a completer
|
if (!c || !isShortcut) // do not process the shortcut when we have a completer
|
||||||
QTextEdit::keyPressEvent(e);
|
QTextEdit::keyPressEvent(e);
|
||||||
//! [7]
|
//! [7]
|
||||||
|
|
||||||
//! [8]
|
//! [8]
|
||||||
const bool ctrlOrShift = e->modifiers() & (Qt::ControlModifier | Qt::ShiftModifier);
|
const bool ctrlOrShift = e->modifiers().testFlag(Qt::ControlModifier) ||
|
||||||
|
e->modifiers().testFlag(Qt::ShiftModifier);
|
||||||
if (!c || (ctrlOrShift && e->text().isEmpty()))
|
if (!c || (ctrlOrShift && e->text().isEmpty()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
static QString eow("~!@#$%^&*()_+{}|:\"<>?,./;'[]\\-="); // end of word
|
static QString eow("~!@#$%^&*()_+{}|:\"<>?,./;'[]\\-="); // end of word
|
||||||
bool hasModifier = (e->modifiers() != Qt::NoModifier) && !ctrlOrShift;
|
const bool hasModifier = (e->modifiers() != Qt::NoModifier) && !ctrlOrShift;
|
||||||
QString completionPrefix = textUnderCursor();
|
QString completionPrefix = textUnderCursor();
|
||||||
|
|
||||||
if (!isShortcut && (hasModifier || e->text().isEmpty()|| completionPrefix.length() < 3
|
if (!isShortcut && (hasModifier || e->text().isEmpty()|| completionPrefix.length() < 3
|
||||||
|
@ -63,7 +63,7 @@ class TextEdit : public QTextEdit
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TextEdit(QWidget *parent = 0);
|
TextEdit(QWidget *parent = nullptr);
|
||||||
~TextEdit();
|
~TextEdit();
|
||||||
|
|
||||||
void setCompleter(QCompleter *c);
|
void setCompleter(QCompleter *c);
|
||||||
@ -80,7 +80,7 @@ private:
|
|||||||
QString textUnderCursor() const;
|
QString textUnderCursor() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QCompleter *c;
|
QCompleter *c = nullptr;
|
||||||
};
|
};
|
||||||
//! [0]
|
//! [0]
|
||||||
|
|
||||||
|
@ -51,13 +51,14 @@
|
|||||||
#ifndef ECHOINTERFACE_H
|
#ifndef ECHOINTERFACE_H
|
||||||
#define ECHOINTERFACE_H
|
#define ECHOINTERFACE_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
//! [0]
|
//! [0]
|
||||||
class EchoInterface
|
class EchoInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~EchoInterface() {}
|
virtual ~EchoInterface() = default;
|
||||||
virtual QString echo(const QString &message) = 0;
|
virtual QString echo(const QString &message) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -48,10 +48,17 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <QtWidgets>
|
|
||||||
|
|
||||||
#include "echowindow.h"
|
#include "echowindow.h"
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QLayout>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QPluginLoader>
|
||||||
|
#include <QPushButton>
|
||||||
|
|
||||||
//! [0]
|
//! [0]
|
||||||
EchoWindow::EchoWindow()
|
EchoWindow::EchoWindow()
|
||||||
{
|
{
|
||||||
@ -101,7 +108,7 @@ void EchoWindow::createGUI()
|
|||||||
//! [3]
|
//! [3]
|
||||||
bool EchoWindow::loadPlugin()
|
bool EchoWindow::loadPlugin()
|
||||||
{
|
{
|
||||||
QDir pluginsDir(qApp->applicationDirPath());
|
QDir pluginsDir(QCoreApplication::applicationDirPath());
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
if (pluginsDir.dirName().toLower() == "debug" || pluginsDir.dirName().toLower() == "release")
|
if (pluginsDir.dirName().toLower() == "debug" || pluginsDir.dirName().toLower() == "release")
|
||||||
pluginsDir.cdUp();
|
pluginsDir.cdUp();
|
||||||
@ -121,6 +128,7 @@ bool EchoWindow::loadPlugin()
|
|||||||
echoInterface = qobject_cast<EchoInterface *>(plugin);
|
echoInterface = qobject_cast<EchoInterface *>(plugin);
|
||||||
if (echoInterface)
|
if (echoInterface)
|
||||||
return true;
|
return true;
|
||||||
|
pluginLoader.unload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <QtWidgets>
|
#include <QApplication>
|
||||||
|
|
||||||
#include "echowindow.h"
|
#include "echowindow.h"
|
||||||
#include "echointerface.h"
|
#include "echointerface.h"
|
||||||
|
@ -48,8 +48,6 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <QtWidgets>
|
|
||||||
|
|
||||||
#include "echoplugin.h"
|
#include "echoplugin.h"
|
||||||
|
|
||||||
//! [0]
|
//! [0]
|
||||||
|
@ -48,34 +48,39 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <QtWidgets>
|
|
||||||
|
|
||||||
#include "languagechooser.h"
|
#include "languagechooser.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
|
||||||
LanguageChooser::LanguageChooser(const QString& defaultLang, QWidget *parent)
|
#include <QCoreApplication>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QDialogButtonBox>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QGridLayout>
|
||||||
|
#include <QGroupBox>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QTranslator>
|
||||||
|
|
||||||
|
LanguageChooser::LanguageChooser(const QString &defaultLang, QWidget *parent)
|
||||||
: QDialog(parent, Qt::WindowStaysOnTopHint)
|
: QDialog(parent, Qt::WindowStaysOnTopHint)
|
||||||
{
|
{
|
||||||
groupBox = new QGroupBox("Languages");
|
groupBox = new QGroupBox("Languages");
|
||||||
|
|
||||||
QGridLayout *groupBoxLayout = new QGridLayout;
|
QGridLayout *groupBoxLayout = new QGridLayout;
|
||||||
|
|
||||||
QStringList qmFiles = findQmFiles();
|
const QStringList qmFiles = findQmFiles();
|
||||||
for (int i = 0; i < qmFiles.size(); ++i) {
|
for (int i = 0; i < qmFiles.size(); ++i) {
|
||||||
QCheckBox *checkBox = new QCheckBox(languageName(qmFiles[i]));
|
const QString &qmlFile = qmFiles.at(i);
|
||||||
qmFileForCheckBoxMap.insert(checkBox, qmFiles[i]);
|
QCheckBox *checkBox = new QCheckBox(languageName(qmlFile));
|
||||||
connect(checkBox,
|
qmFileForCheckBoxMap.insert(checkBox, qmlFile);
|
||||||
QOverload<bool>::of(&QCheckBox::toggled),
|
connect(checkBox, &QCheckBox::toggled,
|
||||||
this,
|
this, &LanguageChooser::checkBoxToggled);
|
||||||
&LanguageChooser::checkBoxToggled);
|
if (languageMatch(defaultLang, qmlFile))
|
||||||
if (languageMatch(defaultLang, qmFiles[i]))
|
checkBox->setCheckState(Qt::Checked);
|
||||||
checkBox->setCheckState(Qt::Checked);
|
|
||||||
groupBoxLayout->addWidget(checkBox, i / 2, i % 2);
|
groupBoxLayout->addWidget(checkBox, i / 2, i % 2);
|
||||||
}
|
}
|
||||||
groupBox->setLayout(groupBoxLayout);
|
groupBox->setLayout(groupBoxLayout);
|
||||||
|
|
||||||
buttonBox = new QDialogButtonBox;
|
buttonBox = new QDialogButtonBox;
|
||||||
|
|
||||||
showAllButton = buttonBox->addButton("Show All",
|
showAllButton = buttonBox->addButton("Show All",
|
||||||
QDialogButtonBox::ActionRole);
|
QDialogButtonBox::ActionRole);
|
||||||
hideAllButton = buttonBox->addButton("Hide All",
|
hideAllButton = buttonBox->addButton("Hide All",
|
||||||
@ -92,7 +97,7 @@ LanguageChooser::LanguageChooser(const QString& defaultLang, QWidget *parent)
|
|||||||
setWindowTitle("I18N");
|
setWindowTitle("I18N");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LanguageChooser::languageMatch(const QString& lang, const QString& qmFile)
|
bool LanguageChooser::languageMatch(const QString &lang, const QString &qmFile)
|
||||||
{
|
{
|
||||||
//qmFile: i18n_xx.qm
|
//qmFile: i18n_xx.qm
|
||||||
const QString prefix = "i18n_";
|
const QString prefix = "i18n_";
|
||||||
@ -110,21 +115,21 @@ bool LanguageChooser::eventFilter(QObject *object, QEvent *event)
|
|||||||
checkBox->setChecked(false);
|
checkBox->setChecked(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return QWidget::eventFilter(object, event);
|
return QDialog::eventFilter(object, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LanguageChooser::closeEvent(QCloseEvent * /* event */)
|
void LanguageChooser::closeEvent(QCloseEvent * /* event */)
|
||||||
{
|
{
|
||||||
qApp->quit();
|
QCoreApplication::quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LanguageChooser::checkBoxToggled()
|
void LanguageChooser::checkBoxToggled()
|
||||||
{
|
{
|
||||||
QCheckBox *checkBox = qobject_cast<QCheckBox *>(sender());
|
QCheckBox *checkBox = qobject_cast<QCheckBox *>(sender());
|
||||||
MainWindow *window = mainWindowForCheckBoxMap[checkBox];
|
MainWindow *window = mainWindowForCheckBoxMap.value(checkBox);
|
||||||
if (!window) {
|
if (!window) {
|
||||||
QTranslator translator;
|
QTranslator translator;
|
||||||
translator.load(qmFileForCheckBoxMap[checkBox]);
|
translator.load(qmFileForCheckBoxMap.value(checkBox));
|
||||||
qApp->installTranslator(&translator);
|
qApp->installTranslator(&translator);
|
||||||
|
|
||||||
window = new MainWindow;
|
window = new MainWindow;
|
||||||
|
@ -52,7 +52,7 @@
|
|||||||
#define LANGUAGECHOOSER_H
|
#define LANGUAGECHOOSER_H
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QMap>
|
#include <QHash>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
@ -68,7 +68,7 @@ class LanguageChooser : public QDialog
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit LanguageChooser(const QString& defaultLang = QString(), QWidget *parent = 0);
|
explicit LanguageChooser(const QString &defaultLang = QString(), QWidget *parent = nullptr);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool eventFilter(QObject *object, QEvent *event) override;
|
bool eventFilter(QObject *object, QEvent *event) override;
|
||||||
@ -80,17 +80,17 @@ private slots:
|
|||||||
void hideAll();
|
void hideAll();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QStringList findQmFiles();
|
static QStringList findQmFiles();
|
||||||
QString languageName(const QString &qmFile);
|
static QString languageName(const QString &qmFile);
|
||||||
QColor colorForLanguage(const QString &language);
|
static QColor colorForLanguage(const QString &language);
|
||||||
static bool languageMatch(const QString& lang, const QString& qmFile);
|
static bool languageMatch(const QString &lang, const QString &qmFile);
|
||||||
|
|
||||||
QGroupBox *groupBox;
|
QGroupBox *groupBox;
|
||||||
QDialogButtonBox *buttonBox;
|
QDialogButtonBox *buttonBox;
|
||||||
QAbstractButton *showAllButton;
|
QAbstractButton *showAllButton;
|
||||||
QAbstractButton *hideAllButton;
|
QAbstractButton *hideAllButton;
|
||||||
QMap<QCheckBox *, QString> qmFileForCheckBoxMap;
|
QHash<QCheckBox *, QString> qmFileForCheckBoxMap;
|
||||||
QMap<QCheckBox *, MainWindow *> mainWindowForCheckBoxMap;
|
QHash<QCheckBox *, MainWindow *> mainWindowForCheckBoxMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -48,18 +48,26 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <QtWidgets>
|
|
||||||
|
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
|
||||||
|
#include <QAction>
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QGroupBox>
|
||||||
|
#include <QListWidget>
|
||||||
|
#include <QMenuBar>
|
||||||
|
#include <QRadioButton>
|
||||||
|
#include <QStatusBar>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
static const char * const listEntries[] = {
|
static const char * const listEntries[] = {
|
||||||
QT_TRANSLATE_NOOP("MainWindow", "First"),
|
QT_TRANSLATE_NOOP("MainWindow", "First"),
|
||||||
QT_TRANSLATE_NOOP("MainWindow", "Second"),
|
QT_TRANSLATE_NOOP("MainWindow", "Second"),
|
||||||
QT_TRANSLATE_NOOP("MainWindow", "Third"),
|
QT_TRANSLATE_NOOP("MainWindow", "Third"),
|
||||||
0
|
nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
MainWindow::MainWindow()
|
MainWindow::MainWindow(QWidget *parent)
|
||||||
|
: QMainWindow(parent)
|
||||||
{
|
{
|
||||||
centralWidget = new QWidget;
|
centralWidget = new QWidget;
|
||||||
setCentralWidget(centralWidget);
|
setCentralWidget(centralWidget);
|
||||||
@ -67,8 +75,8 @@ MainWindow::MainWindow()
|
|||||||
createGroupBox();
|
createGroupBox();
|
||||||
|
|
||||||
listWidget = new QListWidget;
|
listWidget = new QListWidget;
|
||||||
for (int i = 0; listEntries[i]; ++i)
|
for (const char *entry : listEntries)
|
||||||
listWidget->addItem(tr(listEntries[i]));
|
listWidget->addItem(tr(entry));
|
||||||
|
|
||||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||||
mainLayout->addWidget(groupBox);
|
mainLayout->addWidget(groupBox);
|
||||||
@ -76,7 +84,7 @@ MainWindow::MainWindow()
|
|||||||
centralWidget->setLayout(mainLayout);
|
centralWidget->setLayout(mainLayout);
|
||||||
|
|
||||||
exitAction = new QAction(tr("E&xit"), this);
|
exitAction = new QAction(tr("E&xit"), this);
|
||||||
connect(exitAction, &QAction::triggered, qApp, QApplication::quit);
|
connect(exitAction, &QAction::triggered, qApp, QCoreApplication::quit);
|
||||||
|
|
||||||
fileMenu = menuBar()->addMenu(tr("&File"));
|
fileMenu = menuBar()->addMenu(tr("&File"));
|
||||||
fileMenu->setPalette(QPalette(Qt::red));
|
fileMenu->setPalette(QPalette(Qt::red));
|
||||||
|
@ -67,7 +67,7 @@ class MainWindow : public QMainWindow
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MainWindow();
|
MainWindow(QWidget *parent = nullptr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void createGroupBox();
|
void createGroupBox();
|
||||||
|
@ -49,8 +49,8 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#include "interfaces.h"
|
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
#include "interfaces.h"
|
||||||
#include "paintarea.h"
|
#include "paintarea.h"
|
||||||
#include "plugindialog.h"
|
#include "plugindialog.h"
|
||||||
|
|
||||||
@ -67,9 +67,8 @@
|
|||||||
#include <QScrollArea>
|
#include <QScrollArea>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
MainWindow::MainWindow() :
|
MainWindow::MainWindow() : paintArea(new PaintArea)
|
||||||
paintArea(new PaintArea),
|
, scrollArea(new QScrollArea)
|
||||||
scrollArea(new QScrollArea)
|
|
||||||
{
|
{
|
||||||
scrollArea->setBackgroundRole(QPalette::Dark);
|
scrollArea->setBackgroundRole(QPalette::Dark);
|
||||||
scrollArea->setWidget(paintArea);
|
scrollArea->setWidget(paintArea);
|
||||||
@ -136,7 +135,11 @@ void MainWindow::brushWidth()
|
|||||||
void MainWindow::changeBrush()
|
void MainWindow::changeBrush()
|
||||||
{
|
{
|
||||||
auto action = qobject_cast<QAction *>(sender());
|
auto action = qobject_cast<QAction *>(sender());
|
||||||
|
if (!action)
|
||||||
|
return;
|
||||||
auto iBrush = qobject_cast<BrushInterface *>(action->parent());
|
auto iBrush = qobject_cast<BrushInterface *>(action->parent());
|
||||||
|
if (!iBrush)
|
||||||
|
return;
|
||||||
const QString brush = action->text();
|
const QString brush = action->text();
|
||||||
|
|
||||||
paintArea->setBrush(iBrush, brush);
|
paintArea->setBrush(iBrush, brush);
|
||||||
@ -147,7 +150,11 @@ void MainWindow::changeBrush()
|
|||||||
void MainWindow::insertShape()
|
void MainWindow::insertShape()
|
||||||
{
|
{
|
||||||
auto action = qobject_cast<QAction *>(sender());
|
auto action = qobject_cast<QAction *>(sender());
|
||||||
|
if (!action)
|
||||||
|
return;
|
||||||
auto iShape = qobject_cast<ShapeInterface *>(action->parent());
|
auto iShape = qobject_cast<ShapeInterface *>(action->parent());
|
||||||
|
if (!iShape)
|
||||||
|
return;
|
||||||
|
|
||||||
const QPainterPath path = iShape->generateShape(action->text(), this);
|
const QPainterPath path = iShape->generateShape(action->text(), this);
|
||||||
if (!path.isEmpty())
|
if (!path.isEmpty())
|
||||||
@ -159,7 +166,11 @@ void MainWindow::insertShape()
|
|||||||
void MainWindow::applyFilter()
|
void MainWindow::applyFilter()
|
||||||
{
|
{
|
||||||
auto action = qobject_cast<QAction *>(sender());
|
auto action = qobject_cast<QAction *>(sender());
|
||||||
|
if (!action)
|
||||||
|
return;
|
||||||
auto iFilter = qobject_cast<FilterInterface *>(action->parent());
|
auto iFilter = qobject_cast<FilterInterface *>(action->parent());
|
||||||
|
if (!iFilter)
|
||||||
|
return;
|
||||||
|
|
||||||
const QImage image = iFilter->filterImage(action->text(), paintArea->image(),
|
const QImage image = iFilter->filterImage(action->text(), paintArea->image(),
|
||||||
this);
|
this);
|
||||||
@ -247,7 +258,7 @@ void MainWindow::loadPlugins()
|
|||||||
populateMenus(plugin);
|
populateMenus(plugin);
|
||||||
//! [4] //! [5]
|
//! [4] //! [5]
|
||||||
|
|
||||||
pluginsDir = QDir(qApp->applicationDirPath());
|
pluginsDir = QDir(QCoreApplication::applicationDirPath());
|
||||||
|
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
if (pluginsDir.dirName().toLower() == "debug" || pluginsDir.dirName().toLower() == "release")
|
if (pluginsDir.dirName().toLower() == "debug" || pluginsDir.dirName().toLower() == "release")
|
||||||
|
@ -49,14 +49,13 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#include "interfaces.h"
|
|
||||||
#include "paintarea.h"
|
#include "paintarea.h"
|
||||||
|
#include "interfaces.h"
|
||||||
|
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
|
||||||
PaintArea::PaintArea(QWidget *parent) :
|
PaintArea::PaintArea(QWidget *parent) : QWidget(parent)
|
||||||
QWidget(parent)
|
|
||||||
{
|
{
|
||||||
setAttribute(Qt::WA_StaticContents);
|
setAttribute(Qt::WA_StaticContents);
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||||
|
@ -49,8 +49,8 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#include "interfaces.h"
|
|
||||||
#include "plugindialog.h"
|
#include "plugindialog.h"
|
||||||
|
#include "interfaces.h"
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QGridLayout>
|
#include <QGridLayout>
|
||||||
|
@ -50,10 +50,10 @@
|
|||||||
|
|
||||||
#include "basictoolsplugin.h"
|
#include "basictoolsplugin.h"
|
||||||
|
|
||||||
|
#include <QInputDialog>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QRandomGenerator>
|
||||||
#include <QtMath>
|
#include <QtMath>
|
||||||
#include <QtWidgets>
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
//! [0]
|
//! [0]
|
||||||
QStringList BasicToolsPlugin::brushes() const
|
QStringList BasicToolsPlugin::brushes() const
|
||||||
|
@ -54,12 +54,12 @@
|
|||||||
//! [0]
|
//! [0]
|
||||||
#include <interfaces.h>
|
#include <interfaces.h>
|
||||||
|
|
||||||
#include <QRect>
|
|
||||||
#include <QObject>
|
|
||||||
#include <QtPlugin>
|
|
||||||
#include <QStringList>
|
|
||||||
#include <QPainterPath>
|
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
|
#include <QObject>
|
||||||
|
#include <QPainterPath>
|
||||||
|
#include <QRect>
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QtPlugin>
|
||||||
|
|
||||||
//! [1]
|
//! [1]
|
||||||
class BasicToolsPlugin : public QObject,
|
class BasicToolsPlugin : public QObject,
|
||||||
|
@ -50,10 +50,7 @@
|
|||||||
|
|
||||||
#include "extrafiltersplugin.h"
|
#include "extrafiltersplugin.h"
|
||||||
|
|
||||||
#include <QtWidgets>
|
#include <QInputDialog>
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
QStringList ExtraFiltersPlugin::filters() const
|
QStringList ExtraFiltersPlugin::filters() const
|
||||||
{
|
{
|
||||||
|
@ -65,7 +65,7 @@ class RegExpDialog : public QDialog
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RegExpDialog(QWidget *parent = 0);
|
RegExpDialog(QWidget *parent = nullptr);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void refresh();
|
void refresh();
|
||||||
|
@ -70,7 +70,7 @@ class RegularExpressionDialog : public QDialog
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RegularExpressionDialog(QWidget *parent = 0);
|
RegularExpressionDialog(QWidget *parent = nullptr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void refresh();
|
void refresh();
|
||||||
|
@ -48,10 +48,20 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <QtWidgets>
|
|
||||||
|
|
||||||
#include "locationdialog.h"
|
#include "locationdialog.h"
|
||||||
|
|
||||||
|
#include <QBoxLayout>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QDialogButtonBox>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QGroupBox>
|
||||||
|
#include <QHeaderView>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QTableWidget>
|
||||||
|
#include <QTableWidgetItem>
|
||||||
|
|
||||||
LocationDialog::LocationDialog(QWidget *parent)
|
LocationDialog::LocationDialog(QWidget *parent)
|
||||||
: QDialog(parent)
|
: QDialog(parent)
|
||||||
{
|
{
|
||||||
@ -91,8 +101,7 @@ LocationDialog::LocationDialog(QWidget *parent)
|
|||||||
|
|
||||||
locationsGroupBox = new QGroupBox(tr("Setting Locations"));
|
locationsGroupBox = new QGroupBox(tr("Setting Locations"));
|
||||||
|
|
||||||
QStringList labels;
|
const QStringList labels{tr("Location"), tr("Access")};
|
||||||
labels << tr("Location") << tr("Access");
|
|
||||||
|
|
||||||
locationsTable = new QTableWidget;
|
locationsTable = new QTableWidget;
|
||||||
locationsTable->setSelectionMode(QAbstractItemView::SingleSelection);
|
locationsTable->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||||
|
@ -68,7 +68,7 @@ class LocationDialog : public QDialog
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LocationDialog(QWidget *parent = 0);
|
LocationDialog(QWidget *parent = nullptr);
|
||||||
|
|
||||||
QSettings::Format format() const;
|
QSettings::Format format() const;
|
||||||
QSettings::Scope scope() const;
|
QSettings::Scope scope() const;
|
||||||
|
@ -48,15 +48,23 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <QtWidgets>
|
|
||||||
|
|
||||||
#include "locationdialog.h"
|
#include "locationdialog.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "settingstree.h"
|
#include "settingstree.h"
|
||||||
|
|
||||||
MainWindow::MainWindow()
|
#include <QAction>
|
||||||
: settingsTree(new SettingsTree)
|
#include <QApplication>
|
||||||
, locationDialog(nullptr)
|
#include <QDesktopWidget>
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QInputDialog>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QMenuBar>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QStandardPaths>
|
||||||
|
#include <QStatusBar>
|
||||||
|
|
||||||
|
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
|
||||||
|
, settingsTree(new SettingsTree)
|
||||||
{
|
{
|
||||||
setCentralWidget(settingsTree);
|
setCentralWidget(settingsTree);
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ class MainWindow : public QMainWindow
|
|||||||
public:
|
public:
|
||||||
typedef QSharedPointer<QSettings> SettingsPtr;
|
typedef QSharedPointer<QSettings> SettingsPtr;
|
||||||
|
|
||||||
MainWindow();
|
MainWindow(QWidget *parent = nullptr);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void openSettings();
|
void openSettings();
|
||||||
@ -81,11 +81,11 @@ private:
|
|||||||
void createActions();
|
void createActions();
|
||||||
void setSettingsObject(const SettingsPtr &settings);
|
void setSettingsObject(const SettingsPtr &settings);
|
||||||
|
|
||||||
SettingsTree *settingsTree;
|
SettingsTree *settingsTree = nullptr;
|
||||||
LocationDialog *locationDialog;
|
LocationDialog *locationDialog = nullptr;
|
||||||
QAction *refreshAct;
|
QAction *refreshAct = nullptr;
|
||||||
QAction *autoRefreshAct;
|
QAction *autoRefreshAct = nullptr;
|
||||||
QAction *fallbacksAct;
|
QAction *fallbacksAct = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -48,20 +48,20 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <QtWidgets>
|
|
||||||
|
|
||||||
#include "settingstree.h"
|
#include "settingstree.h"
|
||||||
#include "variantdelegate.h"
|
#include "variantdelegate.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QDesktopWidget>
|
||||||
|
#include <QHeaderView>
|
||||||
|
#include <QSettings>
|
||||||
|
|
||||||
SettingsTree::SettingsTree(QWidget *parent)
|
SettingsTree::SettingsTree(QWidget *parent)
|
||||||
: QTreeWidget(parent)
|
: QTreeWidget(parent)
|
||||||
, autoRefresh(false)
|
|
||||||
{
|
{
|
||||||
setItemDelegate(new VariantDelegate(this));
|
setItemDelegate(new VariantDelegate(this));
|
||||||
|
|
||||||
QStringList labels;
|
setHeaderLabels({tr("Setting"), tr("Type"), tr("Value")});
|
||||||
labels << tr("Setting") << tr("Type") << tr("Value");
|
|
||||||
setHeaderLabels(labels);
|
|
||||||
header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
|
header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
|
||||||
header()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
|
header()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
|
||||||
header()->setSectionResizeMode(2, QHeaderView::Stretch);
|
header()->setSectionResizeMode(2, QHeaderView::Stretch);
|
||||||
@ -77,10 +77,6 @@ SettingsTree::SettingsTree(QWidget *parent)
|
|||||||
connect(&refreshTimer, &QTimer::timeout, this, &SettingsTree::maybeRefresh);
|
connect(&refreshTimer, &QTimer::timeout, this, &SettingsTree::maybeRefresh);
|
||||||
}
|
}
|
||||||
|
|
||||||
SettingsTree::~SettingsTree()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void SettingsTree::setSettingsObject(const SettingsPtr &newSettings)
|
void SettingsTree::setSettingsObject(const SettingsPtr &newSettings)
|
||||||
{
|
{
|
||||||
settings = newSettings;
|
settings = newSettings;
|
||||||
@ -137,7 +133,7 @@ void SettingsTree::refresh()
|
|||||||
this, &SettingsTree::updateSetting);
|
this, &SettingsTree::updateSetting);
|
||||||
|
|
||||||
settings->sync();
|
settings->sync();
|
||||||
updateChildItems(0);
|
updateChildItems(nullptr);
|
||||||
|
|
||||||
connect(this, &QTreeWidget::itemChanged,
|
connect(this, &QTreeWidget::itemChanged,
|
||||||
this, &SettingsTree::updateSetting);
|
this, &SettingsTree::updateSetting);
|
||||||
@ -228,7 +224,7 @@ void SettingsTree::updateChildItems(QTreeWidgetItem *parent)
|
|||||||
QTreeWidgetItem *SettingsTree::createItem(const QString &text,
|
QTreeWidgetItem *SettingsTree::createItem(const QString &text,
|
||||||
QTreeWidgetItem *parent, int index)
|
QTreeWidgetItem *parent, int index)
|
||||||
{
|
{
|
||||||
QTreeWidgetItem *after = 0;
|
QTreeWidgetItem *after = nullptr;
|
||||||
if (index != 0)
|
if (index != 0)
|
||||||
after = childAt(parent, index - 1);
|
after = childAt(parent, index - 1);
|
||||||
|
|
||||||
@ -243,24 +239,18 @@ QTreeWidgetItem *SettingsTree::createItem(const QString &text,
|
|||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTreeWidgetItem *SettingsTree::childAt(QTreeWidgetItem *parent, int index)
|
QTreeWidgetItem *SettingsTree::childAt(QTreeWidgetItem *parent, int index) const
|
||||||
{
|
{
|
||||||
if (parent)
|
return (parent ? parent->child(index) : topLevelItem(index));
|
||||||
return parent->child(index);
|
|
||||||
else
|
|
||||||
return topLevelItem(index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int SettingsTree::childCount(QTreeWidgetItem *parent)
|
int SettingsTree::childCount(QTreeWidgetItem *parent) const
|
||||||
{
|
{
|
||||||
if (parent)
|
return (parent ? parent->childCount() : topLevelItemCount());
|
||||||
return parent->childCount();
|
|
||||||
else
|
|
||||||
return topLevelItemCount();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int SettingsTree::findChild(QTreeWidgetItem *parent, const QString &text,
|
int SettingsTree::findChild(QTreeWidgetItem *parent, const QString &text,
|
||||||
int startIndex)
|
int startIndex) const
|
||||||
{
|
{
|
||||||
for (int i = startIndex; i < childCount(parent); ++i) {
|
for (int i = startIndex; i < childCount(parent); ++i) {
|
||||||
if (childAt(parent, i)->text(0) == text)
|
if (childAt(parent, i)->text(0) == text)
|
||||||
|
@ -65,10 +65,9 @@ class SettingsTree : public QTreeWidget
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef QSharedPointer<QSettings> SettingsPtr;
|
using SettingsPtr = QSharedPointer<QSettings>;
|
||||||
|
|
||||||
SettingsTree(QWidget *parent = 0);
|
SettingsTree(QWidget *parent = nullptr);
|
||||||
~SettingsTree();
|
|
||||||
|
|
||||||
void setSettingsObject(const SettingsPtr &settings);
|
void setSettingsObject(const SettingsPtr &settings);
|
||||||
QSize sizeHint() const override;
|
QSize sizeHint() const override;
|
||||||
@ -89,16 +88,16 @@ private:
|
|||||||
void updateChildItems(QTreeWidgetItem *parent);
|
void updateChildItems(QTreeWidgetItem *parent);
|
||||||
QTreeWidgetItem *createItem(const QString &text, QTreeWidgetItem *parent,
|
QTreeWidgetItem *createItem(const QString &text, QTreeWidgetItem *parent,
|
||||||
int index);
|
int index);
|
||||||
QTreeWidgetItem *childAt(QTreeWidgetItem *parent, int index);
|
QTreeWidgetItem *childAt(QTreeWidgetItem *parent, int index) const;
|
||||||
int childCount(QTreeWidgetItem *parent);
|
int childCount(QTreeWidgetItem *parent) const;
|
||||||
int findChild(QTreeWidgetItem *parent, const QString &text, int startIndex);
|
int findChild(QTreeWidgetItem *parent, const QString &text, int startIndex) const;
|
||||||
void moveItemForward(QTreeWidgetItem *parent, int oldIndex, int newIndex);
|
void moveItemForward(QTreeWidgetItem *parent, int oldIndex, int newIndex);
|
||||||
|
|
||||||
SettingsPtr settings;
|
SettingsPtr settings;
|
||||||
QTimer refreshTimer;
|
QTimer refreshTimer;
|
||||||
bool autoRefresh;
|
|
||||||
QIcon groupIcon;
|
QIcon groupIcon;
|
||||||
QIcon keyIcon;
|
QIcon keyIcon;
|
||||||
|
bool autoRefresh = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -48,12 +48,14 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <QtWidgets>
|
|
||||||
|
|
||||||
#include "variantdelegate.h"
|
#include "variantdelegate.h"
|
||||||
|
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QRegularExpressionValidator>
|
||||||
|
|
||||||
VariantDelegate::VariantDelegate(QObject *parent)
|
VariantDelegate::VariantDelegate(QObject *parent)
|
||||||
: QItemDelegate(parent)
|
: QStyledItemDelegate(parent)
|
||||||
{
|
{
|
||||||
boolExp.setPattern("true|false");
|
boolExp.setPattern("true|false");
|
||||||
boolExp.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
|
boolExp.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
|
||||||
@ -82,12 +84,12 @@ void VariantDelegate::paint(QPainter *painter,
|
|||||||
if (!isSupportedType(value.type())) {
|
if (!isSupportedType(value.type())) {
|
||||||
QStyleOptionViewItem myOption = option;
|
QStyleOptionViewItem myOption = option;
|
||||||
myOption.state &= ~QStyle::State_Enabled;
|
myOption.state &= ~QStyle::State_Enabled;
|
||||||
QItemDelegate::paint(painter, myOption, index);
|
QStyledItemDelegate::paint(painter, myOption, index);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QItemDelegate::paint(painter, option, index);
|
QStyledItemDelegate::paint(painter, option, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget *VariantDelegate::createEditor(QWidget *parent,
|
QWidget *VariantDelegate::createEditor(QWidget *parent,
|
||||||
@ -95,11 +97,11 @@ QWidget *VariantDelegate::createEditor(QWidget *parent,
|
|||||||
const QModelIndex &index) const
|
const QModelIndex &index) const
|
||||||
{
|
{
|
||||||
if (index.column() != 2)
|
if (index.column() != 2)
|
||||||
return 0;
|
return nullptr;
|
||||||
|
|
||||||
QVariant originalValue = index.model()->data(index, Qt::UserRole);
|
QVariant originalValue = index.model()->data(index, Qt::UserRole);
|
||||||
if (!isSupportedType(originalValue.type()))
|
if (!isSupportedType(originalValue.type()))
|
||||||
return 0;
|
return nullptr;
|
||||||
|
|
||||||
QLineEdit *lineEdit = new QLineEdit(parent);
|
QLineEdit *lineEdit = new QLineEdit(parent);
|
||||||
lineEdit->setFrame(false);
|
lineEdit->setFrame(false);
|
||||||
@ -149,7 +151,7 @@ QWidget *VariantDelegate::createEditor(QWidget *parent,
|
|||||||
regExp = unsignedIntegerExp;
|
regExp = unsignedIntegerExp;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (regExp.isValid()) {
|
if (regExp.isValid()) {
|
||||||
|
@ -51,15 +51,15 @@
|
|||||||
#ifndef VARIANTDELEGATE_H
|
#ifndef VARIANTDELEGATE_H
|
||||||
#define VARIANTDELEGATE_H
|
#define VARIANTDELEGATE_H
|
||||||
|
|
||||||
#include <QItemDelegate>
|
#include <QStyledItemDelegate>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
|
|
||||||
class VariantDelegate : public QItemDelegate
|
class VariantDelegate : public QStyledItemDelegate
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
VariantDelegate(QObject *parent = 0);
|
VariantDelegate(QObject *parent = nullptr);
|
||||||
|
|
||||||
void paint(QPainter *painter, const QStyleOptionViewItem &option,
|
void paint(QPainter *painter, const QStyleOptionViewItem &option,
|
||||||
const QModelIndex &index) const override;
|
const QModelIndex &index) const override;
|
||||||
|
@ -48,8 +48,6 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <QtWidgets>
|
|
||||||
|
|
||||||
#include "simplestyle.h"
|
#include "simplestyle.h"
|
||||||
|
|
||||||
void SimpleStyle::polish(QPalette &palette)
|
void SimpleStyle::polish(QPalette &palette)
|
||||||
|
@ -53,16 +53,12 @@
|
|||||||
|
|
||||||
#include <QProxyStyle>
|
#include <QProxyStyle>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
|
||||||
class QPalette;
|
|
||||||
QT_END_NAMESPACE
|
|
||||||
|
|
||||||
class SimpleStyle : public QProxyStyle
|
class SimpleStyle : public QProxyStyle
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SimpleStyle() {};
|
SimpleStyle() = default;
|
||||||
|
|
||||||
void polish(QPalette &palette) override;
|
void polish(QPalette &palette) override;
|
||||||
};
|
};
|
||||||
|
@ -48,15 +48,13 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <QtWidgets>
|
|
||||||
|
|
||||||
#include "simplestyleplugin.h"
|
#include "simplestyleplugin.h"
|
||||||
#include "simplestyle.h"
|
#include "simplestyle.h"
|
||||||
|
|
||||||
//! [0]
|
//! [0]
|
||||||
QStringList SimpleStylePlugin::keys() const
|
QStringList SimpleStylePlugin::keys() const
|
||||||
{
|
{
|
||||||
return QStringList() << "SimpleStyle";
|
return {"SimpleStyle"};
|
||||||
}
|
}
|
||||||
//! [0]
|
//! [0]
|
||||||
|
|
||||||
@ -65,6 +63,6 @@ QStyle *SimpleStylePlugin::create(const QString &key)
|
|||||||
{
|
{
|
||||||
if (key.toLower() == "simplestyle")
|
if (key.toLower() == "simplestyle")
|
||||||
return new SimpleStyle;
|
return new SimpleStyle;
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
//! [1]
|
//! [1]
|
||||||
|
@ -53,11 +53,6 @@
|
|||||||
|
|
||||||
#include <QStylePlugin>
|
#include <QStylePlugin>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
|
||||||
class QStringList;
|
|
||||||
class QStyle;
|
|
||||||
QT_END_NAMESPACE
|
|
||||||
|
|
||||||
//! [0]
|
//! [0]
|
||||||
class SimpleStylePlugin : public QStylePlugin
|
class SimpleStylePlugin : public QStylePlugin
|
||||||
{
|
{
|
||||||
@ -65,7 +60,7 @@ class SimpleStylePlugin : public QStylePlugin
|
|||||||
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QStyleFactoryInterface" FILE "simplestyle.json")
|
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QStyleFactoryInterface" FILE "simplestyle.json")
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SimpleStylePlugin() {}
|
SimpleStylePlugin() = default;
|
||||||
|
|
||||||
QStringList keys() const;
|
QStringList keys() const;
|
||||||
QStyle *create(const QString &key) override;
|
QStyle *create(const QString &key) override;
|
||||||
|
@ -48,7 +48,8 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <QtWidgets>
|
#include <QApplication>
|
||||||
|
#include <QStyleFactory>
|
||||||
|
|
||||||
#include "stylewindow.h"
|
#include "stylewindow.h"
|
||||||
|
|
||||||
|
@ -48,7 +48,9 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <QtWidgets>
|
#include <QGridLayout>
|
||||||
|
#include <QGroupBox>
|
||||||
|
#include <QPushButton>
|
||||||
|
|
||||||
#include "stylewindow.h"
|
#include "stylewindow.h"
|
||||||
|
|
||||||
|
@ -48,13 +48,28 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <QtWidgets>
|
|
||||||
#include "treemodelcompleter.h"
|
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
#include "treemodelcompleter.h"
|
||||||
|
|
||||||
|
#include <QAbstractProxyModel>
|
||||||
|
#include <QAction>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QGridLayout>
|
||||||
|
#include <QHeaderView>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QMenuBar>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QStandardItemModel>
|
||||||
|
#include <QStringListModel>
|
||||||
|
#include <QTreeView>
|
||||||
|
|
||||||
//! [0]
|
//! [0]
|
||||||
MainWindow::MainWindow(QWidget *parent)
|
MainWindow::MainWindow(QWidget *parent)
|
||||||
: QMainWindow(parent), completer(0), lineEdit(0)
|
: QMainWindow(parent)
|
||||||
{
|
{
|
||||||
createMenu();
|
createMenu();
|
||||||
|
|
||||||
@ -151,10 +166,10 @@ void MainWindow::createMenu()
|
|||||||
connect(aboutAct, &QAction::triggered, this, &MainWindow::about);
|
connect(aboutAct, &QAction::triggered, this, &MainWindow::about);
|
||||||
connect(aboutQtAct, &QAction::triggered, qApp, &QApplication::aboutQt);
|
connect(aboutQtAct, &QAction::triggered, qApp, &QApplication::aboutQt);
|
||||||
|
|
||||||
QMenu* fileMenu = menuBar()->addMenu(tr("File"));
|
QMenu *fileMenu = menuBar()->addMenu(tr("File"));
|
||||||
fileMenu->addAction(exitAction);
|
fileMenu->addAction(exitAction);
|
||||||
|
|
||||||
QMenu* helpMenu = menuBar()->addMenu(tr("About"));
|
QMenu *helpMenu = menuBar()->addMenu(tr("About"));
|
||||||
helpMenu->addAction(aboutAct);
|
helpMenu->addAction(aboutAct);
|
||||||
helpMenu->addAction(aboutQtAct);
|
helpMenu->addAction(aboutQtAct);
|
||||||
}
|
}
|
||||||
@ -175,7 +190,7 @@ void MainWindow::changeMode(int index)
|
|||||||
}
|
}
|
||||||
//! [5]
|
//! [5]
|
||||||
|
|
||||||
QAbstractItemModel *MainWindow::modelFromFile(const QString& fileName)
|
QAbstractItemModel *MainWindow::modelFromFile(const QString &fileName)
|
||||||
{
|
{
|
||||||
QFile file(fileName);
|
QFile file(fileName);
|
||||||
if (!file.open(QFile::ReadOnly))
|
if (!file.open(QFile::ReadOnly))
|
||||||
@ -184,39 +199,35 @@ QAbstractItemModel *MainWindow::modelFromFile(const QString& fileName)
|
|||||||
#ifndef QT_NO_CURSOR
|
#ifndef QT_NO_CURSOR
|
||||||
QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
|
QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
|
||||||
#endif
|
#endif
|
||||||
QStringList words;
|
|
||||||
|
|
||||||
QStandardItemModel *model = new QStandardItemModel(completer);
|
QStandardItemModel *model = new QStandardItemModel(completer);
|
||||||
QVector<QStandardItem *> parents(10);
|
QVector<QStandardItem *> parents(10);
|
||||||
parents[0] = model->invisibleRootItem();
|
parents[0] = model->invisibleRootItem();
|
||||||
|
|
||||||
|
QRegularExpression re("^\\s+");
|
||||||
while (!file.atEnd()) {
|
while (!file.atEnd()) {
|
||||||
QString line = file.readLine();
|
const QString line = QString::fromUtf8(file.readLine()).trimmed();
|
||||||
QString trimmedLine = line.trimmed();
|
const QString trimmedLine = line.trimmed();
|
||||||
if (line.isEmpty() || trimmedLine.isEmpty())
|
if (trimmedLine.isEmpty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
QRegularExpression re("^\\s+");
|
const QRegularExpressionMatch match = re.match(line);
|
||||||
QRegularExpressionMatch match = re.match(line);
|
|
||||||
int nonws = match.capturedStart();
|
int nonws = match.capturedStart();
|
||||||
int level = 0;
|
int level = 0;
|
||||||
if (nonws == -1) {
|
if (nonws == -1) {
|
||||||
level = 0;
|
level = 0;
|
||||||
} else {
|
} else {
|
||||||
if (line.startsWith("\t")) {
|
const int capLen = match.capturedLength();
|
||||||
level = match.capturedLength();
|
level = line.startsWith(QLatin1Char('\t')) ? capLen / 4 : capLen;
|
||||||
} else {
|
|
||||||
level = match.capturedLength()/4;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (level+1 >= parents.size())
|
if (level + 1 >= parents.size())
|
||||||
parents.resize(parents.size()*2);
|
parents.resize(parents.size() * 2);
|
||||||
|
|
||||||
QStandardItem *item = new QStandardItem;
|
QStandardItem *item = new QStandardItem;
|
||||||
item->setText(trimmedLine);
|
item->setText(trimmedLine);
|
||||||
parents[level]->appendRow(item);
|
parents[level]->appendRow(item);
|
||||||
parents[level+1] = item;
|
parents[level + 1] = item;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef QT_NO_CURSOR
|
#ifndef QT_NO_CURSOR
|
||||||
@ -252,7 +263,7 @@ void MainWindow::changeCase(int cs)
|
|||||||
}
|
}
|
||||||
//! [7]
|
//! [7]
|
||||||
|
|
||||||
void MainWindow::updateContentsLabel(const QString& sep)
|
void MainWindow::updateContentsLabel(const QString &sep)
|
||||||
{
|
{
|
||||||
contentsLabel->setText(tr("Type path from model above with items at each level separated by a '%1'").arg(sep));
|
contentsLabel->setText(tr("Type path from model above with items at each level separated by a '%1'").arg(sep));
|
||||||
}
|
}
|
||||||
|
@ -60,8 +60,6 @@ class QAbstractItemModel;
|
|||||||
class QComboBox;
|
class QComboBox;
|
||||||
class QLabel;
|
class QLabel;
|
||||||
class QLineEdit;
|
class QLineEdit;
|
||||||
class QProgressBar;
|
|
||||||
class QCheckBox;
|
|
||||||
class QTreeView;
|
class QTreeView;
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
@ -71,27 +69,27 @@ class MainWindow : public QMainWindow
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MainWindow(QWidget *parent = 0);
|
MainWindow(QWidget *parent = nullptr);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void about();
|
void about();
|
||||||
void changeCase(int);
|
void changeCase(int);
|
||||||
void changeMode(int);
|
void changeMode(int);
|
||||||
void highlight(const QModelIndex&);
|
void highlight(const QModelIndex &index);
|
||||||
void updateContentsLabel(const QString&);
|
void updateContentsLabel(const QString &sep);
|
||||||
//! [0]
|
//! [0]
|
||||||
|
|
||||||
//! [1]
|
//! [1]
|
||||||
private:
|
private:
|
||||||
void createMenu();
|
void createMenu();
|
||||||
QAbstractItemModel *modelFromFile(const QString& fileName);
|
QAbstractItemModel *modelFromFile(const QString &fileName);
|
||||||
|
|
||||||
QTreeView *treeView;
|
QTreeView *treeView = nullptr;
|
||||||
QComboBox *caseCombo;
|
QComboBox *caseCombo = nullptr;
|
||||||
QComboBox *modeCombo;
|
QComboBox *modeCombo = nullptr;
|
||||||
QLabel *contentsLabel;
|
QLabel *contentsLabel = nullptr;
|
||||||
TreeModelCompleter *completer;
|
TreeModelCompleter *completer = nullptr;
|
||||||
QLineEdit *lineEdit;
|
QLineEdit *lineEdit = nullptr;
|
||||||
};
|
};
|
||||||
//! [1]
|
//! [1]
|
||||||
|
|
||||||
|
@ -80,26 +80,20 @@ QString TreeModelCompleter::separator() const
|
|||||||
//! [3]
|
//! [3]
|
||||||
QStringList TreeModelCompleter::splitPath(const QString &path) const
|
QStringList TreeModelCompleter::splitPath(const QString &path) const
|
||||||
{
|
{
|
||||||
if (sep.isNull()) {
|
return (sep.isNull() ? QCompleter::splitPath(path) : path.split(sep));
|
||||||
return QCompleter::splitPath(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
return path.split(sep);
|
|
||||||
}
|
}
|
||||||
//! [3]
|
//! [3]
|
||||||
|
|
||||||
//! [4]
|
//! [4]
|
||||||
QString TreeModelCompleter::pathFromIndex(const QModelIndex &index) const
|
QString TreeModelCompleter::pathFromIndex(const QModelIndex &index) const
|
||||||
{
|
{
|
||||||
if (sep.isNull()) {
|
if (sep.isNull())
|
||||||
return QCompleter::pathFromIndex(index);
|
return QCompleter::pathFromIndex(index);
|
||||||
}
|
|
||||||
|
|
||||||
// navigate up and accumulate data
|
// navigate up and accumulate data
|
||||||
QStringList dataList;
|
QStringList dataList;
|
||||||
for (QModelIndex i = index; i.isValid(); i = i.parent()) {
|
for (QModelIndex i = index; i.isValid(); i = i.parent())
|
||||||
dataList.prepend(model()->data(i, completionRole()).toString());
|
dataList.prepend(model()->data(i, completionRole()).toString());
|
||||||
}
|
|
||||||
|
|
||||||
return dataList.join(sep);
|
return dataList.join(sep);
|
||||||
}
|
}
|
||||||
|
@ -60,8 +60,8 @@ class TreeModelCompleter : public QCompleter
|
|||||||
Q_PROPERTY(QString separator READ separator WRITE setSeparator)
|
Q_PROPERTY(QString separator READ separator WRITE setSeparator)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit TreeModelCompleter(QObject *parent = 0);
|
explicit TreeModelCompleter(QObject *parent = nullptr);
|
||||||
explicit TreeModelCompleter(QAbstractItemModel *model, QObject *parent = 0);
|
explicit TreeModelCompleter(QAbstractItemModel *model, QObject *parent = nullptr);
|
||||||
|
|
||||||
QString separator() const;
|
QString separator() const;
|
||||||
public slots:
|
public slots:
|
||||||
|
@ -50,18 +50,16 @@
|
|||||||
|
|
||||||
#include "commands.h"
|
#include "commands.h"
|
||||||
|
|
||||||
static const int setShapeRectCommandId = 1;
|
static constexpr int setShapeRectCommandId = 1;
|
||||||
static const int setShapeColorCommandId = 2;
|
static constexpr int setShapeColorCommandId = 2;
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
** AddShapeCommand
|
** AddShapeCommand
|
||||||
*/
|
*/
|
||||||
|
|
||||||
AddShapeCommand::AddShapeCommand(Document *doc, const Shape &shape, QUndoCommand *parent)
|
AddShapeCommand::AddShapeCommand(Document *doc, const Shape &shape, QUndoCommand *parent)
|
||||||
: QUndoCommand(parent)
|
: QUndoCommand(parent), m_doc(doc), m_shape(shape)
|
||||||
{
|
{
|
||||||
m_doc = doc;
|
|
||||||
m_shape = shape;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddShapeCommand::undo()
|
void AddShapeCommand::undo()
|
||||||
@ -81,13 +79,11 @@ void AddShapeCommand::redo()
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
RemoveShapeCommand::RemoveShapeCommand(Document *doc, const QString &shapeName,
|
RemoveShapeCommand::RemoveShapeCommand(Document *doc, const QString &shapeName,
|
||||||
QUndoCommand *parent)
|
QUndoCommand *parent)
|
||||||
: QUndoCommand(parent)
|
: QUndoCommand(parent), m_doc(doc), m_shape(doc->shape(shapeName))
|
||||||
|
, m_shapeName(shapeName)
|
||||||
{
|
{
|
||||||
setText(QObject::tr("Remove %1").arg(shapeName));
|
setText(QObject::tr("Remove %1").arg(shapeName));
|
||||||
m_doc = doc;
|
|
||||||
m_shape = doc->shape(shapeName);
|
|
||||||
m_shapeName = shapeName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoveShapeCommand::undo()
|
void RemoveShapeCommand::undo()
|
||||||
@ -105,15 +101,11 @@ void RemoveShapeCommand::redo()
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
SetShapeColorCommand::SetShapeColorCommand(Document *doc, const QString &shapeName,
|
SetShapeColorCommand::SetShapeColorCommand(Document *doc, const QString &shapeName,
|
||||||
const QColor &color, QUndoCommand *parent)
|
const QColor &color, QUndoCommand *parent)
|
||||||
: QUndoCommand(parent)
|
: QUndoCommand(parent), m_doc(doc), m_shapeName(shapeName)
|
||||||
|
, m_oldColor(doc->shape(shapeName).color()), m_newColor(color)
|
||||||
{
|
{
|
||||||
setText(QObject::tr("Set %1's color").arg(shapeName));
|
setText(QObject::tr("Set %1's color").arg(shapeName));
|
||||||
|
|
||||||
m_doc = doc;
|
|
||||||
m_shapeName = shapeName;
|
|
||||||
m_oldColor = doc->shape(shapeName).color();
|
|
||||||
m_newColor = color;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetShapeColorCommand::undo()
|
void SetShapeColorCommand::undo()
|
||||||
@ -149,15 +141,11 @@ int SetShapeColorCommand::id() const
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
SetShapeRectCommand::SetShapeRectCommand(Document *doc, const QString &shapeName,
|
SetShapeRectCommand::SetShapeRectCommand(Document *doc, const QString &shapeName,
|
||||||
const QRect &rect, QUndoCommand *parent)
|
const QRect &rect, QUndoCommand *parent)
|
||||||
: QUndoCommand(parent)
|
: QUndoCommand(parent), m_doc(doc), m_shapeName(shapeName)
|
||||||
|
, m_oldRect(doc->shape(shapeName).rect()), m_newRect(rect)
|
||||||
{
|
{
|
||||||
setText(QObject::tr("Change %1's geometry").arg(shapeName));
|
setText(QObject::tr("Change %1's geometry").arg(shapeName));
|
||||||
|
|
||||||
m_doc = doc;
|
|
||||||
m_shapeName = shapeName;
|
|
||||||
m_oldRect = doc->shape(shapeName).rect();
|
|
||||||
m_newRect = rect;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetShapeRectCommand::undo()
|
void SetShapeRectCommand::undo()
|
||||||
|
@ -57,7 +57,8 @@
|
|||||||
class AddShapeCommand : public QUndoCommand
|
class AddShapeCommand : public QUndoCommand
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AddShapeCommand(Document *doc, const Shape &shape, QUndoCommand *parent = 0);
|
AddShapeCommand(Document *doc, const Shape &shape,
|
||||||
|
QUndoCommand *parent = nullptr);
|
||||||
void undo() override;
|
void undo() override;
|
||||||
void redo() override;
|
void redo() override;
|
||||||
|
|
||||||
@ -70,7 +71,8 @@ private:
|
|||||||
class RemoveShapeCommand : public QUndoCommand
|
class RemoveShapeCommand : public QUndoCommand
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RemoveShapeCommand(Document *doc, const QString &shapeName, QUndoCommand *parent = 0);
|
RemoveShapeCommand(Document *doc, const QString &shapeName,
|
||||||
|
QUndoCommand *parent = nullptr);
|
||||||
void undo() override;
|
void undo() override;
|
||||||
void redo() override;
|
void redo() override;
|
||||||
|
|
||||||
@ -83,8 +85,8 @@ private:
|
|||||||
class SetShapeColorCommand : public QUndoCommand
|
class SetShapeColorCommand : public QUndoCommand
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SetShapeColorCommand(Document *doc, const QString &shapeName, const QColor &color,
|
SetShapeColorCommand(Document *doc, const QString &shapeName,
|
||||||
QUndoCommand *parent = 0);
|
const QColor &color, QUndoCommand *parent = nullptr);
|
||||||
|
|
||||||
void undo() override;
|
void undo() override;
|
||||||
void redo() override;
|
void redo() override;
|
||||||
@ -102,8 +104,8 @@ private:
|
|||||||
class SetShapeRectCommand : public QUndoCommand
|
class SetShapeRectCommand : public QUndoCommand
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SetShapeRectCommand(Document *doc, const QString &shapeName, const QRect &rect,
|
SetShapeRectCommand(Document *doc, const QString &shapeName,
|
||||||
QUndoCommand *parent = 0);
|
const QRect &rect, QUndoCommand *parent = nullptr);
|
||||||
|
|
||||||
void undo() override;
|
void undo() override;
|
||||||
void redo() override;
|
void redo() override;
|
||||||
|
@ -48,14 +48,15 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <qevent.h>
|
|
||||||
#include <QPainter>
|
|
||||||
#include <QTextStream>
|
|
||||||
#include <QUndoStack>
|
|
||||||
#include "document.h"
|
#include "document.h"
|
||||||
#include "commands.h"
|
#include "commands.h"
|
||||||
|
|
||||||
static const int resizeHandleWidth = 6;
|
#include <QPainter>
|
||||||
|
#include <QPaintEvent>
|
||||||
|
#include <QTextStream>
|
||||||
|
#include <QUndoStack>
|
||||||
|
|
||||||
|
static constexpr int resizeHandleWidth = 6;
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
** Shape
|
** Shape
|
||||||
@ -96,26 +97,21 @@ QRect Shape::resizeHandle() const
|
|||||||
|
|
||||||
QString Shape::typeToString(Type type)
|
QString Shape::typeToString(Type type)
|
||||||
{
|
{
|
||||||
QString result;
|
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Rectangle:
|
case Rectangle:
|
||||||
result = QLatin1String("Rectangle");
|
return QLatin1String("Rectangle");
|
||||||
break;
|
|
||||||
case Circle:
|
case Circle:
|
||||||
result = QLatin1String("Circle");
|
return QLatin1String("Circle");
|
||||||
break;
|
|
||||||
case Triangle:
|
case Triangle:
|
||||||
result = QLatin1String("Triangle");
|
return QLatin1String("Triangle");
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
Shape::Type Shape::stringToType(const QString &s, bool *ok)
|
Shape::Type Shape::stringToType(const QString &s, bool *ok)
|
||||||
{
|
{
|
||||||
if (ok != 0)
|
if (ok != nullptr)
|
||||||
*ok = true;
|
*ok = true;
|
||||||
|
|
||||||
if (s == QLatin1String("Rectangle"))
|
if (s == QLatin1String("Rectangle"))
|
||||||
@ -125,7 +121,7 @@ Shape::Type Shape::stringToType(const QString &s, bool *ok)
|
|||||||
if (s == QLatin1String("Triangle"))
|
if (s == QLatin1String("Triangle"))
|
||||||
return Triangle;
|
return Triangle;
|
||||||
|
|
||||||
if (ok != 0)
|
if (ok != nullptr)
|
||||||
*ok = false;
|
*ok = false;
|
||||||
return Rectangle;
|
return Rectangle;
|
||||||
}
|
}
|
||||||
@ -135,10 +131,8 @@ Shape::Type Shape::stringToType(const QString &s, bool *ok)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
Document::Document(QWidget *parent)
|
Document::Document(QWidget *parent)
|
||||||
: QWidget(parent), m_currentIndex(-1), m_mousePressIndex(-1), m_resizeHandlePressed(false)
|
: QWidget(parent), m_undoStack(new QUndoStack(this))
|
||||||
{
|
{
|
||||||
m_undoStack = new QUndoStack(this);
|
|
||||||
|
|
||||||
setAutoFillBackground(true);
|
setAutoFillBackground(true);
|
||||||
setBackgroundRole(QPalette::Base);
|
setBackgroundRole(QPalette::Base);
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ public:
|
|||||||
QColor color() const;
|
QColor color() const;
|
||||||
|
|
||||||
static QString typeToString(Type type);
|
static QString typeToString(Type type);
|
||||||
static Type stringToType(const QString &s, bool *ok = 0);
|
static Type stringToType(const QString &s, bool *ok = nullptr);
|
||||||
|
|
||||||
static const QSize minSize;
|
static const QSize minSize;
|
||||||
|
|
||||||
@ -88,7 +88,7 @@ class Document : public QWidget
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Document(QWidget *parent = 0);
|
Document(QWidget *parent = nullptr);
|
||||||
|
|
||||||
QString addShape(const Shape &shape);
|
QString addShape(const Shape &shape);
|
||||||
void deleteShape(const QString &shapeName);
|
void deleteShape(const QString &shapeName);
|
||||||
@ -121,14 +121,13 @@ private:
|
|||||||
int indexAt(const QPoint &pos) const;
|
int indexAt(const QPoint &pos) const;
|
||||||
QString uniqueName(const QString &name) const;
|
QString uniqueName(const QString &name) const;
|
||||||
|
|
||||||
QList<Shape> m_shapeList;
|
QVector<Shape> m_shapeList;
|
||||||
int m_currentIndex;
|
|
||||||
int m_mousePressIndex;
|
|
||||||
QPoint m_mousePressOffset;
|
QPoint m_mousePressOffset;
|
||||||
bool m_resizeHandlePressed;
|
|
||||||
QString m_fileName;
|
QString m_fileName;
|
||||||
|
QUndoStack *m_undoStack = nullptr;
|
||||||
QUndoStack *m_undoStack;
|
int m_currentIndex = -1;
|
||||||
|
int m_mousePressIndex = -1;
|
||||||
|
bool m_resizeHandlePressed = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DOCUMENT_H
|
#endif // DOCUMENT_H
|
||||||
|
@ -48,6 +48,10 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "mainwindow.h"
|
||||||
|
#include "document.h"
|
||||||
|
#include "commands.h"
|
||||||
|
|
||||||
#include <QUndoGroup>
|
#include <QUndoGroup>
|
||||||
#include <QUndoStack>
|
#include <QUndoStack>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
@ -55,9 +59,6 @@
|
|||||||
#include <QRandomGenerator>
|
#include <QRandomGenerator>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
#include <QToolButton>
|
#include <QToolButton>
|
||||||
#include "document.h"
|
|
||||||
#include "mainwindow.h"
|
|
||||||
#include "commands.h"
|
|
||||||
|
|
||||||
MainWindow::MainWindow(QWidget *parent)
|
MainWindow::MainWindow(QWidget *parent)
|
||||||
: QMainWindow(parent)
|
: QMainWindow(parent)
|
||||||
@ -122,17 +123,17 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
void MainWindow::updateActions()
|
void MainWindow::updateActions()
|
||||||
{
|
{
|
||||||
Document *doc = currentDocument();
|
Document *doc = currentDocument();
|
||||||
m_undoGroup->setActiveStack(doc == 0 ? 0 : doc->undoStack());
|
m_undoGroup->setActiveStack(doc == nullptr ? nullptr : doc->undoStack());
|
||||||
QString shapeName = doc == 0 ? QString() : doc->currentShapeName();
|
QString shapeName = doc == nullptr ? QString() : doc->currentShapeName();
|
||||||
|
|
||||||
actionAddRobot->setEnabled(doc != 0);
|
actionAddRobot->setEnabled(doc != nullptr);
|
||||||
actionAddSnowman->setEnabled(doc != 0);
|
actionAddSnowman->setEnabled(doc != nullptr);
|
||||||
actionAddCircle->setEnabled(doc != 0);
|
actionAddCircle->setEnabled(doc != nullptr);
|
||||||
actionAddRectangle->setEnabled(doc != 0);
|
actionAddRectangle->setEnabled(doc != nullptr);
|
||||||
actionAddTriangle->setEnabled(doc != 0);
|
actionAddTriangle->setEnabled(doc != nullptr);
|
||||||
actionClose->setEnabled(doc != 0);
|
actionClose->setEnabled(doc != nullptr);
|
||||||
actionSave->setEnabled(doc != 0 && !doc->undoStack()->isClean());
|
actionSave->setEnabled(doc != nullptr && !doc->undoStack()->isClean());
|
||||||
undoLimit->setEnabled(doc != 0 && doc->undoStack()->count() == 0);
|
undoLimit->setEnabled(doc != nullptr && doc->undoStack()->count() == 0);
|
||||||
|
|
||||||
if (shapeName.isEmpty()) {
|
if (shapeName.isEmpty()) {
|
||||||
actionRed->setEnabled(false);
|
actionRed->setEnabled(false);
|
||||||
@ -147,7 +148,7 @@ void MainWindow::updateActions()
|
|||||||
actionRemoveShape->setEnabled(true);
|
actionRemoveShape->setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doc != 0) {
|
if (doc != nullptr) {
|
||||||
int index = documentTabs->indexOf(doc);
|
int index = documentTabs->indexOf(doc);
|
||||||
Q_ASSERT(index != -1);
|
Q_ASSERT(index != -1);
|
||||||
static const QIcon unsavedIcon(":/icons/filesave.png");
|
static const QIcon unsavedIcon(":/icons/filesave.png");
|
||||||
@ -264,7 +265,7 @@ void MainWindow::removeDocument(Document *doc)
|
|||||||
void MainWindow::saveDocument()
|
void MainWindow::saveDocument()
|
||||||
{
|
{
|
||||||
Document *doc = currentDocument();
|
Document *doc = currentDocument();
|
||||||
if (doc == 0)
|
if (doc == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@ -298,7 +299,7 @@ void MainWindow::saveDocument()
|
|||||||
void MainWindow::closeDocument()
|
void MainWindow::closeDocument()
|
||||||
{
|
{
|
||||||
Document *doc = currentDocument();
|
Document *doc = currentDocument();
|
||||||
if (doc == 0)
|
if (doc == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!doc->undoStack()->isClean()) {
|
if (!doc->undoStack()->isClean()) {
|
||||||
@ -338,10 +339,10 @@ static QRect randomRect(const QSize &s)
|
|||||||
{
|
{
|
||||||
QSize min = Shape::minSize;
|
QSize min = Shape::minSize;
|
||||||
|
|
||||||
int left = (int) ((0.0 + s.width() - min.width())*(QRandomGenerator::global()->bounded(1.0)));
|
int left = qRound((s.width() - min.width()) * (QRandomGenerator::global()->bounded(1.0)));
|
||||||
int top = (int) ((0.0 + s.height() - min.height())*(QRandomGenerator::global()->bounded(1.0)));
|
int top = qRound((s.height() - min.height()) * (QRandomGenerator::global()->bounded(1.0)));
|
||||||
int width = (int) ((0.0 + s.width() - left - min.width())*(QRandomGenerator::global()->bounded(1.0))) + min.width();
|
int width = qRound((s.width() - left - min.width()) * (QRandomGenerator::global()->bounded(1.0))) + min.width();
|
||||||
int height = (int) ((0.0 + s.height() - top - min.height())*(QRandomGenerator::global()->bounded(1.0))) + min.height();
|
int height = qRound((s.height() - top - min.height()) * (QRandomGenerator::global()->bounded(1.0))) + min.height();
|
||||||
|
|
||||||
return QRect(left, top, width, height);
|
return QRect(left, top, width, height);
|
||||||
}
|
}
|
||||||
@ -349,7 +350,7 @@ static QRect randomRect(const QSize &s)
|
|||||||
void MainWindow::addShape()
|
void MainWindow::addShape()
|
||||||
{
|
{
|
||||||
Document *doc = currentDocument();
|
Document *doc = currentDocument();
|
||||||
if (doc == 0)
|
if (doc == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Shape::Type type;
|
Shape::Type type;
|
||||||
@ -369,7 +370,7 @@ void MainWindow::addShape()
|
|||||||
void MainWindow::removeShape()
|
void MainWindow::removeShape()
|
||||||
{
|
{
|
||||||
Document *doc = currentDocument();
|
Document *doc = currentDocument();
|
||||||
if (doc == 0)
|
if (doc == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QString shapeName = doc->currentShapeName();
|
QString shapeName = doc->currentShapeName();
|
||||||
@ -382,7 +383,7 @@ void MainWindow::removeShape()
|
|||||||
void MainWindow::setShapeColor()
|
void MainWindow::setShapeColor()
|
||||||
{
|
{
|
||||||
Document *doc = currentDocument();
|
Document *doc = currentDocument();
|
||||||
if (doc == 0)
|
if (doc == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QString shapeName = doc->currentShapeName();
|
QString shapeName = doc->currentShapeName();
|
||||||
@ -409,7 +410,7 @@ void MainWindow::setShapeColor()
|
|||||||
void MainWindow::addSnowman()
|
void MainWindow::addSnowman()
|
||||||
{
|
{
|
||||||
Document *doc = currentDocument();
|
Document *doc = currentDocument();
|
||||||
if (doc == 0)
|
if (doc == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Create a macro command using beginMacro() and endMacro()
|
// Create a macro command using beginMacro() and endMacro()
|
||||||
@ -427,7 +428,7 @@ void MainWindow::addSnowman()
|
|||||||
void MainWindow::addRobot()
|
void MainWindow::addRobot()
|
||||||
{
|
{
|
||||||
Document *doc = currentDocument();
|
Document *doc = currentDocument();
|
||||||
if (doc == 0)
|
if (doc == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Compose a macro command by explicitly adding children to a parent command
|
// Compose a macro command by explicitly adding children to a parent command
|
||||||
|
@ -61,7 +61,7 @@ class MainWindow : public QMainWindow, public Ui::MainWindow
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MainWindow(QWidget *parent = 0);
|
MainWindow(QWidget *parent = nullptr);
|
||||||
|
|
||||||
void addDocument(Document *doc);
|
void addDocument(Document *doc);
|
||||||
void removeDocument(Document *doc);
|
void removeDocument(Document *doc);
|
||||||
|
@ -48,19 +48,17 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <QtWidgets>
|
|
||||||
|
|
||||||
#include "commands.h"
|
#include "commands.h"
|
||||||
#include "diagramitem.h"
|
#include "diagramitem.h"
|
||||||
|
|
||||||
|
#include <QGraphicsScene>
|
||||||
|
|
||||||
//! [0]
|
//! [0]
|
||||||
MoveCommand::MoveCommand(DiagramItem *diagramItem, const QPointF &oldPos,
|
MoveCommand::MoveCommand(DiagramItem *diagramItem, const QPointF &oldPos,
|
||||||
QUndoCommand *parent)
|
QUndoCommand *parent)
|
||||||
: QUndoCommand(parent)
|
: QUndoCommand(parent), myDiagramItem(diagramItem)
|
||||||
|
, myOldPos(oldPos), newPos(diagramItem->pos())
|
||||||
{
|
{
|
||||||
myDiagramItem = diagramItem;
|
|
||||||
newPos = diagramItem->pos();
|
|
||||||
myOldPos = oldPos;
|
|
||||||
}
|
}
|
||||||
//! [0]
|
//! [0]
|
||||||
|
|
||||||
@ -71,7 +69,7 @@ bool MoveCommand::mergeWith(const QUndoCommand *command)
|
|||||||
DiagramItem *item = moveCommand->myDiagramItem;
|
DiagramItem *item = moveCommand->myDiagramItem;
|
||||||
|
|
||||||
if (myDiagramItem != item)
|
if (myDiagramItem != item)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
newPos = item->pos();
|
newPos = item->pos();
|
||||||
setText(QObject::tr("Move %1")
|
setText(QObject::tr("Move %1")
|
||||||
@ -102,9 +100,8 @@ void MoveCommand::redo()
|
|||||||
|
|
||||||
//! [4]
|
//! [4]
|
||||||
DeleteCommand::DeleteCommand(QGraphicsScene *scene, QUndoCommand *parent)
|
DeleteCommand::DeleteCommand(QGraphicsScene *scene, QUndoCommand *parent)
|
||||||
: QUndoCommand(parent)
|
: QUndoCommand(parent), myGraphicsScene(scene)
|
||||||
{
|
{
|
||||||
myGraphicsScene = scene;
|
|
||||||
QList<QGraphicsItem *> list = myGraphicsScene->selectedItems();
|
QList<QGraphicsItem *> list = myGraphicsScene->selectedItems();
|
||||||
list.first()->setSelected(false);
|
list.first()->setSelected(false);
|
||||||
myDiagramItem = static_cast<DiagramItem *>(list.first());
|
myDiagramItem = static_cast<DiagramItem *>(list.first());
|
||||||
@ -131,11 +128,10 @@ void DeleteCommand::redo()
|
|||||||
//! [7]
|
//! [7]
|
||||||
AddCommand::AddCommand(DiagramItem::DiagramType addType,
|
AddCommand::AddCommand(DiagramItem::DiagramType addType,
|
||||||
QGraphicsScene *scene, QUndoCommand *parent)
|
QGraphicsScene *scene, QUndoCommand *parent)
|
||||||
: QUndoCommand(parent)
|
: QUndoCommand(parent), myGraphicsScene(scene)
|
||||||
{
|
{
|
||||||
static int itemCount = 0;
|
static int itemCount = 0;
|
||||||
|
|
||||||
myGraphicsScene = scene;
|
|
||||||
myDiagramItem = new DiagramItem(addType);
|
myDiagramItem = new DiagramItem(addType);
|
||||||
initialPosition = QPointF((itemCount * 15) % int(scene->width()),
|
initialPosition = QPointF((itemCount * 15) % int(scene->width()),
|
||||||
(itemCount * 15) % int(scene->height()));
|
(itemCount * 15) % int(scene->height()));
|
||||||
|
@ -62,7 +62,7 @@ public:
|
|||||||
enum { Id = 1234 };
|
enum { Id = 1234 };
|
||||||
|
|
||||||
MoveCommand(DiagramItem *diagramItem, const QPointF &oldPos,
|
MoveCommand(DiagramItem *diagramItem, const QPointF &oldPos,
|
||||||
QUndoCommand *parent = 0);
|
QUndoCommand *parent = nullptr);
|
||||||
|
|
||||||
void undo() override;
|
void undo() override;
|
||||||
void redo() override;
|
void redo() override;
|
||||||
@ -80,7 +80,7 @@ private:
|
|||||||
class DeleteCommand : public QUndoCommand
|
class DeleteCommand : public QUndoCommand
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit DeleteCommand(QGraphicsScene *graphicsScene, QUndoCommand *parent = 0);
|
explicit DeleteCommand(QGraphicsScene *graphicsScene, QUndoCommand *parent = nullptr);
|
||||||
|
|
||||||
void undo() override;
|
void undo() override;
|
||||||
void redo() override;
|
void redo() override;
|
||||||
@ -96,7 +96,7 @@ class AddCommand : public QUndoCommand
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AddCommand(DiagramItem::DiagramType addType, QGraphicsScene *graphicsScene,
|
AddCommand(DiagramItem::DiagramType addType, QGraphicsScene *graphicsScene,
|
||||||
QUndoCommand *parent = 0);
|
QUndoCommand *parent = nullptr);
|
||||||
~AddCommand();
|
~AddCommand();
|
||||||
|
|
||||||
void undo() override;
|
void undo() override;
|
||||||
|
@ -48,10 +48,11 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <QtWidgets>
|
|
||||||
|
|
||||||
#include "diagramitem.h"
|
#include "diagramitem.h"
|
||||||
|
|
||||||
|
#include <QBrush>
|
||||||
|
#include <QRandomGenerator>
|
||||||
|
|
||||||
DiagramItem::DiagramItem(DiagramType diagramType, QGraphicsItem *item)
|
DiagramItem::DiagramItem(DiagramType diagramType, QGraphicsItem *item)
|
||||||
: QGraphicsPolygonItem(item)
|
: QGraphicsPolygonItem(item)
|
||||||
{
|
{
|
||||||
@ -65,7 +66,9 @@ DiagramItem::DiagramItem(DiagramType diagramType, QGraphicsItem *item)
|
|||||||
setPolygon(trianglePolygon);
|
setPolygon(trianglePolygon);
|
||||||
}
|
}
|
||||||
|
|
||||||
QColor color(QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256));
|
QColor color(QRandomGenerator::global()->bounded(256),
|
||||||
|
QRandomGenerator::global()->bounded(256),
|
||||||
|
QRandomGenerator::global()->bounded(256));
|
||||||
QBrush brush(color);
|
QBrush brush(color);
|
||||||
setBrush(brush);
|
setBrush(brush);
|
||||||
setFlag(QGraphicsItem::ItemIsSelectable);
|
setFlag(QGraphicsItem::ItemIsSelectable);
|
||||||
|
@ -66,9 +66,10 @@ public:
|
|||||||
enum { Type = UserType + 1 };
|
enum { Type = UserType + 1 };
|
||||||
enum DiagramType { Box, Triangle };
|
enum DiagramType { Box, Triangle };
|
||||||
|
|
||||||
explicit DiagramItem(DiagramType diagramType, QGraphicsItem *item = 0);
|
explicit DiagramItem(DiagramType diagramType, QGraphicsItem *item = nullptr);
|
||||||
|
|
||||||
DiagramType diagramType() const {
|
DiagramType diagramType() const
|
||||||
|
{
|
||||||
return polygon() == boxPolygon ? Box : Triangle;
|
return polygon() == boxPolygon ? Box : Triangle;
|
||||||
}
|
}
|
||||||
int type() const override { return Type; }
|
int type() const override { return Type; }
|
||||||
|
@ -48,27 +48,24 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <QtWidgets>
|
|
||||||
|
|
||||||
#include "diagramscene.h"
|
#include "diagramscene.h"
|
||||||
#include "diagramitem.h"
|
#include "diagramitem.h"
|
||||||
|
|
||||||
|
#include <QGraphicsSceneMouseEvent>
|
||||||
|
|
||||||
DiagramScene::DiagramScene(QObject *parent)
|
DiagramScene::DiagramScene(QObject *parent)
|
||||||
: QGraphicsScene(parent)
|
: QGraphicsScene(parent)
|
||||||
{
|
{}
|
||||||
movingItem = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DiagramScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
void DiagramScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||||
{
|
{
|
||||||
QPointF mousePos(event->buttonDownScenePos(Qt::LeftButton).x(),
|
QPointF mousePos(event->buttonDownScenePos(Qt::LeftButton).x(),
|
||||||
event->buttonDownScenePos(Qt::LeftButton).y());
|
event->buttonDownScenePos(Qt::LeftButton).y());
|
||||||
const QList<QGraphicsItem *> itemList = items(mousePos);
|
const QList<QGraphicsItem *> itemList = items(mousePos);
|
||||||
movingItem = itemList.isEmpty() ? 0 : itemList.first();
|
movingItem = itemList.isEmpty() ? nullptr : itemList.first();
|
||||||
|
|
||||||
if (movingItem != 0 && event->button() == Qt::LeftButton) {
|
if (movingItem != nullptr && event->button() == Qt::LeftButton)
|
||||||
oldPos = movingItem->pos();
|
oldPos = movingItem->pos();
|
||||||
}
|
|
||||||
|
|
||||||
clearSelection();
|
clearSelection();
|
||||||
QGraphicsScene::mousePressEvent(event);
|
QGraphicsScene::mousePressEvent(event);
|
||||||
@ -76,11 +73,11 @@ void DiagramScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
|||||||
|
|
||||||
void DiagramScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
void DiagramScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||||
{
|
{
|
||||||
if (movingItem != 0 && event->button() == Qt::LeftButton) {
|
if (movingItem != nullptr && event->button() == Qt::LeftButton) {
|
||||||
if (oldPos != movingItem->pos())
|
if (oldPos != movingItem->pos())
|
||||||
emit itemMoved(qgraphicsitem_cast<DiagramItem *>(movingItem),
|
emit itemMoved(qgraphicsitem_cast<DiagramItem *>(movingItem),
|
||||||
oldPos);
|
oldPos);
|
||||||
movingItem = 0;
|
movingItem = nullptr;
|
||||||
}
|
}
|
||||||
QGraphicsScene::mouseReleaseEvent(event);
|
QGraphicsScene::mouseReleaseEvent(event);
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ class DiagramScene : public QGraphicsScene
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DiagramScene(QObject *parent = 0);
|
DiagramScene(QObject *parent = nullptr);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void itemMoved(DiagramItem *movedItem, const QPointF &movedFromPosition);
|
void itemMoved(DiagramItem *movedItem, const QPointF &movedFromPosition);
|
||||||
@ -76,7 +76,7 @@ protected:
|
|||||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
|
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QGraphicsItem *movingItem;
|
QGraphicsItem *movingItem = nullptr;
|
||||||
QPointF oldPos;
|
QPointF oldPos;
|
||||||
};
|
};
|
||||||
//! [0]
|
//! [0]
|
||||||
|
@ -48,7 +48,7 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <QtWidgets>
|
#include <QApplication>
|
||||||
|
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
|
||||||
|
@ -48,13 +48,18 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <QtWidgets>
|
|
||||||
|
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "diagramscene.h"
|
#include "diagramscene.h"
|
||||||
#include "diagramitem.h"
|
#include "diagramitem.h"
|
||||||
#include "commands.h"
|
#include "commands.h"
|
||||||
|
|
||||||
|
#include <QAction>
|
||||||
|
#include <QGraphicsView>
|
||||||
|
#include <QMenu>
|
||||||
|
#include <QMenuBar>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QUndoView>
|
||||||
|
|
||||||
//! [0]
|
//! [0]
|
||||||
MainWindow::MainWindow()
|
MainWindow::MainWindow()
|
||||||
{
|
{
|
||||||
|
@ -87,22 +87,22 @@ private:
|
|||||||
void createMenus();
|
void createMenus();
|
||||||
void createUndoView();
|
void createUndoView();
|
||||||
|
|
||||||
QAction *deleteAction;
|
QAction *deleteAction = nullptr;
|
||||||
QAction *addBoxAction;
|
QAction *addBoxAction = nullptr;
|
||||||
QAction *addTriangleAction;
|
QAction *addTriangleAction = nullptr;
|
||||||
QAction *undoAction;
|
QAction *undoAction = nullptr;
|
||||||
QAction *redoAction;
|
QAction *redoAction = nullptr;
|
||||||
QAction *exitAction;
|
QAction *exitAction = nullptr;
|
||||||
QAction *aboutAction;
|
QAction *aboutAction = nullptr;
|
||||||
|
|
||||||
QMenu *fileMenu;
|
QMenu *fileMenu = nullptr;
|
||||||
QMenu *editMenu;
|
QMenu *editMenu = nullptr;
|
||||||
QMenu *itemMenu;
|
QMenu *itemMenu = nullptr;
|
||||||
QMenu *helpMenu;
|
QMenu *helpMenu = nullptr;
|
||||||
|
|
||||||
DiagramScene *diagramScene;
|
DiagramScene *diagramScene = nullptr;
|
||||||
QUndoStack *undoStack;
|
QUndoStack *undoStack = nullptr;
|
||||||
QUndoView *undoView;
|
QUndoView *undoView = nullptr;
|
||||||
};
|
};
|
||||||
//! [0]
|
//! [0]
|
||||||
|
|
||||||
|
@ -14,7 +14,6 @@ include(unix.conf)
|
|||||||
|
|
||||||
QMAKE_RESOURCE = /Developer/Tools/Rez
|
QMAKE_RESOURCE = /Developer/Tools/Rez
|
||||||
QMAKE_EXTENSION_SHLIB = dylib
|
QMAKE_EXTENSION_SHLIB = dylib
|
||||||
QMAKE_EXTENSIONS_AUX_SHLIB = tbd
|
|
||||||
QMAKE_LIBDIR =
|
QMAKE_LIBDIR =
|
||||||
|
|
||||||
# sdk.prf will prefix the proper SDK sysroot
|
# sdk.prf will prefix the proper SDK sysroot
|
||||||
|
@ -300,7 +300,8 @@ mac {
|
|||||||
CMAKE_PRL_FILE_LOCATION_RELEASE = lib$${CMAKE_QT_STEM}.prl
|
CMAKE_PRL_FILE_LOCATION_RELEASE = lib$${CMAKE_QT_STEM}.prl
|
||||||
} else {
|
} else {
|
||||||
qt_framework {
|
qt_framework {
|
||||||
CMAKE_LIB_FILE_LOCATION_DEBUG = $${CMAKE_QT_STEM}.framework/$${CMAKE_QT_STEM}_debug
|
# Intentionally there is no '_debug' infix for framework builds.
|
||||||
|
CMAKE_LIB_FILE_LOCATION_DEBUG = $${CMAKE_QT_STEM}.framework/$${CMAKE_QT_STEM}
|
||||||
CMAKE_LIB_FILE_LOCATION_RELEASE = $${CMAKE_QT_STEM}.framework/$${CMAKE_QT_STEM}
|
CMAKE_LIB_FILE_LOCATION_RELEASE = $${CMAKE_QT_STEM}.framework/$${CMAKE_QT_STEM}
|
||||||
CMAKE_BUILD_IS_FRAMEWORK = "true"
|
CMAKE_BUILD_IS_FRAMEWORK = "true"
|
||||||
} else {
|
} else {
|
||||||
|
@ -22,6 +22,8 @@ for(ever) {
|
|||||||
!defined(QMAKE_LIBS_$$nu, var): \
|
!defined(QMAKE_LIBS_$$nu, var): \
|
||||||
error("Library '$$lower($$replace(nu, _, -))' is not defined.")
|
error("Library '$$lower($$replace(nu, _, -))' is not defined.")
|
||||||
|
|
||||||
|
QMAKE_LIBDIR += $$eval(QMAKE_LIBDIR_$$nu)
|
||||||
|
|
||||||
android {
|
android {
|
||||||
ABI_LIBS = $$eval(QMAKE_LIBS_$${nu}_$${QT_ARCH})
|
ABI_LIBS = $$eval(QMAKE_LIBS_$${nu}_$${QT_ARCH})
|
||||||
isEmpty(ABI_LIBS): ABI_LIBS = $$eval(QMAKE_LIBS_$${nu})
|
isEmpty(ABI_LIBS): ABI_LIBS = $$eval(QMAKE_LIBS_$${nu})
|
||||||
|
@ -537,98 +537,23 @@ defineReplace(qtGccSysrootifiedPaths) {
|
|||||||
return($$sysrootified)
|
return($$sysrootified)
|
||||||
}
|
}
|
||||||
|
|
||||||
# libs-var, libs, in-paths, out-paths-var
|
# libs-var, libs, in-paths
|
||||||
defineTest(qtConfResolveLibs) {
|
defineTest(qtConfResolveLibs) {
|
||||||
ret = true
|
for (path, 3): \
|
||||||
paths = $$3
|
pre_lflags += -L$$path
|
||||||
out =
|
$$1 = $$pre_lflags $$2
|
||||||
copy = false
|
|
||||||
for (l, 2) {
|
|
||||||
$$copy {
|
|
||||||
copy = false
|
|
||||||
out += $$l
|
|
||||||
} else: equals(l, "-s") {
|
|
||||||
# em++ flag to link libraries from emscripten-ports; passed on literally.
|
|
||||||
copy = true
|
|
||||||
out += $$l
|
|
||||||
} else: contains(l, "^-L.*") {
|
|
||||||
lp = $$replace(l, "^-L", )
|
|
||||||
gcc: lp = $$qtGccSysrootifiedPath($$lp)
|
|
||||||
!exists($$lp/.) {
|
|
||||||
qtLog("Library path $$val_escape(lp) is invalid.")
|
|
||||||
ret = false
|
|
||||||
} else {
|
|
||||||
paths += $$lp
|
|
||||||
}
|
|
||||||
} else: !android: contains(l, "^-l.*") {
|
|
||||||
lib = $$replace(l, "^-l", )
|
|
||||||
lcan =
|
|
||||||
integrity:contains(lib, "^.*\\.a") {
|
|
||||||
# INTEGRITY compiler searches for exact filename
|
|
||||||
# if -l argument has .a suffix
|
|
||||||
lcan += $${lib}
|
|
||||||
} else: contains(lib, "^:.*") {
|
|
||||||
# Use exact filename when -l:filename syntax is used.
|
|
||||||
lib ~= s/^://
|
|
||||||
lcan += $${lib}
|
|
||||||
} else: unix {
|
|
||||||
# Under UNIX, we look for actual shared libraries, in addition
|
|
||||||
# to static ones.
|
|
||||||
shexts = $$QMAKE_EXTENSION_SHLIB $$QMAKE_EXTENSIONS_AUX_SHLIB
|
|
||||||
for (ext, shexts) {
|
|
||||||
lcan += $${QMAKE_PREFIX_SHLIB}$${lib}.$${ext}
|
|
||||||
}
|
|
||||||
lcan += \
|
|
||||||
$${QMAKE_PREFIX_STATICLIB}$${lib}.$${QMAKE_EXTENSION_STATICLIB}
|
|
||||||
} else {
|
|
||||||
# Under Windows, we look only for static libraries, as even for DLLs
|
|
||||||
# one actually links against a static import library.
|
|
||||||
mingw {
|
|
||||||
lcan += \
|
|
||||||
# MinGW supports UNIX-style library naming in addition to
|
|
||||||
# the MSVC style.
|
|
||||||
lib$${lib}.dll.a lib$${lib}.a \
|
|
||||||
# Fun fact: prefix-less libraries are also supported.
|
|
||||||
$${lib}.dll.a $${lib}.a
|
|
||||||
}
|
|
||||||
lcan += $${lib}.lib
|
|
||||||
}
|
|
||||||
l = $$qtConfFindInPathList($$lcan, $$paths $$EXTRA_LIBDIR $$QMAKE_DEFAULT_LIBDIRS)
|
|
||||||
isEmpty(l) {
|
|
||||||
qtLog("None of [$$val_escape(lcan)] found in [$$val_escape(paths)] and global paths.")
|
|
||||||
ret = false
|
|
||||||
} else {
|
|
||||||
out += $$l
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
out += $$l
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$$1 = $$out
|
|
||||||
export($$1)
|
export($$1)
|
||||||
!isEmpty(4) {
|
return(true)
|
||||||
$$4 = $$paths
|
|
||||||
export($$4)
|
|
||||||
}
|
|
||||||
return($$ret)
|
|
||||||
}
|
|
||||||
|
|
||||||
# source-var
|
|
||||||
defineTest(qtConfResolveAllLibs) {
|
|
||||||
ret = true
|
|
||||||
!qtConfResolveLibs($${1}.libs, $$eval($${1}.libs), , $${1}.libdirs): \
|
|
||||||
ret = false
|
|
||||||
for (b, $${1}.builds._KEYS_): \
|
|
||||||
!qtConfResolveLibs($${1}.builds.$${b}, $$eval($${1}.builds.$${b}), $$eval($${1}.libdirs), ): \
|
|
||||||
ret = false
|
|
||||||
return($$ret)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# libs-var, in-paths, libs
|
# libs-var, in-paths, libs
|
||||||
defineTest(qtConfResolvePathLibs) {
|
defineTest(qtConfResolvePathLibs) {
|
||||||
ret = true
|
ret = true
|
||||||
gcc: 2 = $$qtGccSysrootifiedPaths($$2)
|
gcc: \
|
||||||
for (libdir, 2) {
|
local_paths = $$qtGccSysrootifiedPaths($$2)
|
||||||
|
else: \
|
||||||
|
local_paths = $$2
|
||||||
|
for (libdir, local_paths) {
|
||||||
!exists($$libdir/.) {
|
!exists($$libdir/.) {
|
||||||
qtLog("Library path $$val_escape(libdir) is invalid.")
|
qtLog("Library path $$val_escape(libdir) is invalid.")
|
||||||
ret = false
|
ret = false
|
||||||
@ -678,8 +603,11 @@ defineReplace(qtConfGetTestIncludes) {
|
|||||||
# includes-var, in-paths, test-object-var
|
# includes-var, in-paths, test-object-var
|
||||||
defineTest(qtConfResolvePathIncs) {
|
defineTest(qtConfResolvePathIncs) {
|
||||||
ret = true
|
ret = true
|
||||||
gcc: 2 = $$qtGccSysrootifiedPaths($$2)
|
gcc: \
|
||||||
for (incdir, 2) {
|
local_paths = $$qtGccSysrootifiedPaths($$2)
|
||||||
|
else: \
|
||||||
|
local_paths = $$2
|
||||||
|
for (incdir, local_paths) {
|
||||||
!exists($$incdir/.) {
|
!exists($$incdir/.) {
|
||||||
qtLog("Include path $$val_escape(incdir) is invalid.")
|
qtLog("Include path $$val_escape(incdir) is invalid.")
|
||||||
ret = false
|
ret = false
|
||||||
@ -773,11 +701,9 @@ defineTest(qtConfLibrary_inline) {
|
|||||||
for (ld, libdir): \
|
for (ld, libdir): \
|
||||||
libs += -L$$ld
|
libs += -L$$ld
|
||||||
$${1}.libs = $$libs $$eval($${1}.libs)
|
$${1}.libs = $$libs $$eval($${1}.libs)
|
||||||
|
export($${1}.libs)
|
||||||
}
|
}
|
||||||
|
|
||||||
!qtConfResolveAllLibs($$1): \
|
|
||||||
return(false)
|
|
||||||
|
|
||||||
!qtConfResolvePathIncs($${1}.includedir, $$includes, $$2): \
|
!qtConfResolvePathIncs($${1}.includedir, $$includes, $$2): \
|
||||||
return(false)
|
return(false)
|
||||||
|
|
||||||
|
@ -56,13 +56,13 @@ int main(int argc, char *argv[])
|
|||||||
QTranslator translator;
|
QTranslator translator;
|
||||||
// look up e.g. :/translations/myapp_de.qm
|
// look up e.g. :/translations/myapp_de.qm
|
||||||
if (translator.load(QLocale(), QLatin1String("myapp"), QLatin1String("_"), QLatin1String(":/translations")))
|
if (translator.load(QLocale(), QLatin1String("myapp"), QLatin1String("_"), QLatin1String(":/translations")))
|
||||||
app.installTranslator(&translator);
|
QCoreApplication::installTranslator(&translator);
|
||||||
|
|
||||||
QPushButton hello(QCoreApplication::translate("main", "Hello world!"));
|
QPushButton hello(QCoreApplication::translate("main", "Hello world!"));
|
||||||
hello.resize(100, 30);
|
hello.resize(100, 30);
|
||||||
|
|
||||||
hello.show();
|
hello.show();
|
||||||
return app.exec();
|
return QCoreApplication::exec();
|
||||||
}
|
}
|
||||||
//! [0]
|
//! [0]
|
||||||
|
|
||||||
|
@ -41,9 +41,9 @@
|
|||||||
#include "qfilesystemwatcher_p.h"
|
#include "qfilesystemwatcher_p.h"
|
||||||
|
|
||||||
#include <qdatetime.h>
|
#include <qdatetime.h>
|
||||||
#include <qdebug.h>
|
|
||||||
#include <qdir.h>
|
#include <qdir.h>
|
||||||
#include <qfileinfo.h>
|
#include <qfileinfo.h>
|
||||||
|
#include <qloggingcategory.h>
|
||||||
#include <qset.h>
|
#include <qset.h>
|
||||||
#include <qtimer.h>
|
#include <qtimer.h>
|
||||||
|
|
||||||
@ -67,6 +67,8 @@
|
|||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
Q_LOGGING_CATEGORY(lcWatcher, "qt.core.filesystemwatcher")
|
||||||
|
|
||||||
QFileSystemWatcherEngine *QFileSystemWatcherPrivate::createNativeEngine(QObject *parent)
|
QFileSystemWatcherEngine *QFileSystemWatcherPrivate::createNativeEngine(QObject *parent)
|
||||||
{
|
{
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
@ -137,6 +139,7 @@ void QFileSystemWatcherPrivate::initPollerEngine()
|
|||||||
void QFileSystemWatcherPrivate::_q_fileChanged(const QString &path, bool removed)
|
void QFileSystemWatcherPrivate::_q_fileChanged(const QString &path, bool removed)
|
||||||
{
|
{
|
||||||
Q_Q(QFileSystemWatcher);
|
Q_Q(QFileSystemWatcher);
|
||||||
|
qCDebug(lcWatcher) << "file changed" << path << "removed?" << removed << "watching?" << files.contains(path);
|
||||||
if (!files.contains(path)) {
|
if (!files.contains(path)) {
|
||||||
// the path was removed after a change was detected, but before we delivered the signal
|
// the path was removed after a change was detected, but before we delivered the signal
|
||||||
return;
|
return;
|
||||||
@ -149,6 +152,7 @@ void QFileSystemWatcherPrivate::_q_fileChanged(const QString &path, bool removed
|
|||||||
void QFileSystemWatcherPrivate::_q_directoryChanged(const QString &path, bool removed)
|
void QFileSystemWatcherPrivate::_q_directoryChanged(const QString &path, bool removed)
|
||||||
{
|
{
|
||||||
Q_Q(QFileSystemWatcher);
|
Q_Q(QFileSystemWatcher);
|
||||||
|
qCDebug(lcWatcher) << "directory changed" << path << "removed?" << removed << "watching?" << directories.contains(path);
|
||||||
if (!directories.contains(path)) {
|
if (!directories.contains(path)) {
|
||||||
// perhaps the path was removed after a change was detected, but before we delivered the signal
|
// perhaps the path was removed after a change was detected, but before we delivered the signal
|
||||||
return;
|
return;
|
||||||
@ -355,7 +359,7 @@ QStringList QFileSystemWatcher::addPaths(const QStringList &paths)
|
|||||||
qWarning("QFileSystemWatcher::addPaths: list is empty");
|
qWarning("QFileSystemWatcher::addPaths: list is empty");
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
qCDebug(lcWatcher) << "adding" << paths;
|
||||||
const auto selectEngine = [this, d]() -> QFileSystemWatcherEngine* {
|
const auto selectEngine = [this, d]() -> QFileSystemWatcherEngine* {
|
||||||
#ifdef QT_BUILD_INTERNAL
|
#ifdef QT_BUILD_INTERNAL
|
||||||
const QString on = objectName();
|
const QString on = objectName();
|
||||||
@ -364,11 +368,11 @@ QStringList QFileSystemWatcher::addPaths(const QStringList &paths)
|
|||||||
// Autotest override case - use the explicitly selected engine only
|
// Autotest override case - use the explicitly selected engine only
|
||||||
const QStringRef forceName = on.midRef(26);
|
const QStringRef forceName = on.midRef(26);
|
||||||
if (forceName == QLatin1String("poller")) {
|
if (forceName == QLatin1String("poller")) {
|
||||||
qDebug("QFileSystemWatcher: skipping native engine, using only polling engine");
|
qCDebug(lcWatcher, "QFileSystemWatcher: skipping native engine, using only polling engine");
|
||||||
d_func()->initPollerEngine();
|
d_func()->initPollerEngine();
|
||||||
return d->poller;
|
return d->poller;
|
||||||
} else if (forceName == QLatin1String("native")) {
|
} else if (forceName == QLatin1String("native")) {
|
||||||
qDebug("QFileSystemWatcher: skipping polling engine, using only native engine");
|
qCDebug(lcWatcher, "QFileSystemWatcher: skipping polling engine, using only native engine");
|
||||||
return d->native;
|
return d->native;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -431,6 +435,7 @@ QStringList QFileSystemWatcher::removePaths(const QStringList &paths)
|
|||||||
qWarning("QFileSystemWatcher::removePaths: list is empty");
|
qWarning("QFileSystemWatcher::removePaths: list is empty");
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
qCDebug(lcWatcher) << "removing" << paths;
|
||||||
|
|
||||||
if (d->native)
|
if (d->native)
|
||||||
p = d->native->removePaths(p, &d->files, &d->directories);
|
p = d->native->removePaths(p, &d->files, &d->directories);
|
||||||
|
@ -2693,7 +2693,14 @@ Q_GLOBAL_STATIC(QRecursiveMutex, libraryPathMutex)
|
|||||||
QStringList QCoreApplication::libraryPaths()
|
QStringList QCoreApplication::libraryPaths()
|
||||||
{
|
{
|
||||||
QMutexLocker locker(libraryPathMutex());
|
QMutexLocker locker(libraryPathMutex());
|
||||||
|
return libraryPathsLocked();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\internal
|
||||||
|
*/
|
||||||
|
QStringList QCoreApplication::libraryPathsLocked()
|
||||||
|
{
|
||||||
if (coreappdata()->manual_libpaths)
|
if (coreappdata()->manual_libpaths)
|
||||||
return *(coreappdata()->manual_libpaths);
|
return *(coreappdata()->manual_libpaths);
|
||||||
|
|
||||||
@ -2769,7 +2776,7 @@ void QCoreApplication::setLibraryPaths(const QStringList &paths)
|
|||||||
// When the application is constructed it should still amend the paths. So we keep the originals
|
// When the application is constructed it should still amend the paths. So we keep the originals
|
||||||
// around, and even create them if they don't exist, yet.
|
// around, and even create them if they don't exist, yet.
|
||||||
if (!coreappdata()->app_libpaths)
|
if (!coreappdata()->app_libpaths)
|
||||||
libraryPaths();
|
libraryPathsLocked();
|
||||||
|
|
||||||
if (coreappdata()->manual_libpaths)
|
if (coreappdata()->manual_libpaths)
|
||||||
*(coreappdata()->manual_libpaths) = paths;
|
*(coreappdata()->manual_libpaths) = paths;
|
||||||
@ -2812,7 +2819,7 @@ void QCoreApplication::addLibraryPath(const QString &path)
|
|||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
// make sure that library paths are initialized
|
// make sure that library paths are initialized
|
||||||
libraryPaths();
|
libraryPathsLocked();
|
||||||
QStringList *app_libpaths = coreappdata()->app_libpaths.data();
|
QStringList *app_libpaths = coreappdata()->app_libpaths.data();
|
||||||
if (app_libpaths->contains(canonicalPath))
|
if (app_libpaths->contains(canonicalPath))
|
||||||
return;
|
return;
|
||||||
@ -2851,7 +2858,7 @@ void QCoreApplication::removeLibraryPath(const QString &path)
|
|||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
// make sure that library paths is initialized
|
// make sure that library paths is initialized
|
||||||
libraryPaths();
|
libraryPathsLocked();
|
||||||
QStringList *app_libpaths = coreappdata()->app_libpaths.data();
|
QStringList *app_libpaths = coreappdata()->app_libpaths.data();
|
||||||
if (!app_libpaths->contains(canonicalPath))
|
if (!app_libpaths->contains(canonicalPath))
|
||||||
return;
|
return;
|
||||||
|
@ -208,6 +208,9 @@ private:
|
|||||||
static bool notifyInternal2(QObject *receiver, QEvent *);
|
static bool notifyInternal2(QObject *receiver, QEvent *);
|
||||||
static bool forwardEvent(QObject *receiver, QEvent *event, QEvent *originatingEvent = nullptr);
|
static bool forwardEvent(QObject *receiver, QEvent *event, QEvent *originatingEvent = nullptr);
|
||||||
#endif
|
#endif
|
||||||
|
#if QT_CONFIG(library)
|
||||||
|
static QStringList libraryPathsLocked();
|
||||||
|
#endif
|
||||||
|
|
||||||
static QCoreApplication *self;
|
static QCoreApplication *self;
|
||||||
|
|
||||||
|
@ -54,20 +54,11 @@ class QPointer
|
|||||||
{
|
{
|
||||||
Q_STATIC_ASSERT_X(!std::is_pointer<T>::value, "QPointer's template type must not be a pointer type");
|
Q_STATIC_ASSERT_X(!std::is_pointer<T>::value, "QPointer's template type must not be a pointer type");
|
||||||
|
|
||||||
template<typename U>
|
using QObjectType =
|
||||||
struct TypeSelector
|
typename std::conditional<std::is_const<T>::value, const QObject, QObject>::type;
|
||||||
{
|
|
||||||
typedef QObject Type;
|
|
||||||
};
|
|
||||||
template<typename U>
|
|
||||||
struct TypeSelector<const U>
|
|
||||||
{
|
|
||||||
typedef const QObject Type;
|
|
||||||
};
|
|
||||||
typedef typename TypeSelector<T>::Type QObjectType;
|
|
||||||
QWeakPointer<QObjectType> wp;
|
QWeakPointer<QObjectType> wp;
|
||||||
public:
|
public:
|
||||||
inline QPointer() { }
|
QPointer() = default;
|
||||||
inline QPointer(T *p) : wp(p, true) { }
|
inline QPointer(T *p) : wp(p, true) { }
|
||||||
// compiler-generated copy/move ctor/assignment operators are fine!
|
// compiler-generated copy/move ctor/assignment operators are fine!
|
||||||
// compiler-generated dtor is fine!
|
// compiler-generated dtor is fine!
|
||||||
|
@ -48,6 +48,9 @@
|
|||||||
#include "qreadwritelock_p.h"
|
#include "qreadwritelock_p.h"
|
||||||
#include "qelapsedtimer.h"
|
#include "qelapsedtimer.h"
|
||||||
#include "private/qfreelist_p.h"
|
#include "private/qfreelist_p.h"
|
||||||
|
#include "private/qlocking_p.h"
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
@ -64,6 +67,9 @@ QT_BEGIN_NAMESPACE
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
using ms = std::chrono::milliseconds;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
StateMask = 0x3,
|
StateMask = 0x3,
|
||||||
StateLockedForRead = 0x1,
|
StateLockedForRead = 0x1,
|
||||||
@ -262,7 +268,7 @@ bool QReadWriteLock::tryLockForRead(int timeout)
|
|||||||
if (d->recursive)
|
if (d->recursive)
|
||||||
return d->recursiveLockForRead(timeout);
|
return d->recursiveLockForRead(timeout);
|
||||||
|
|
||||||
QMutexLocker lock(&d->mutex);
|
auto lock = qt_unique_lock(d->mutex);
|
||||||
if (d != d_ptr.loadRelaxed()) {
|
if (d != d_ptr.loadRelaxed()) {
|
||||||
// d_ptr has changed: this QReadWriteLock was unlocked before we had
|
// d_ptr has changed: this QReadWriteLock was unlocked before we had
|
||||||
// time to lock d->mutex.
|
// time to lock d->mutex.
|
||||||
@ -273,7 +279,7 @@ bool QReadWriteLock::tryLockForRead(int timeout)
|
|||||||
d = d_ptr.loadAcquire();
|
d = d_ptr.loadAcquire();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
return d->lockForRead(timeout);
|
return d->lockForRead(lock, timeout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -369,7 +375,7 @@ bool QReadWriteLock::tryLockForWrite(int timeout)
|
|||||||
if (d->recursive)
|
if (d->recursive)
|
||||||
return d->recursiveLockForWrite(timeout);
|
return d->recursiveLockForWrite(timeout);
|
||||||
|
|
||||||
QMutexLocker lock(&d->mutex);
|
auto lock = qt_unique_lock(d->mutex);
|
||||||
if (d != d_ptr.loadRelaxed()) {
|
if (d != d_ptr.loadRelaxed()) {
|
||||||
// The mutex was unlocked before we had time to lock the mutex.
|
// The mutex was unlocked before we had time to lock the mutex.
|
||||||
// We are holding to a mutex within a QReadWriteLockPrivate that is already released
|
// We are holding to a mutex within a QReadWriteLockPrivate that is already released
|
||||||
@ -377,7 +383,7 @@ bool QReadWriteLock::tryLockForWrite(int timeout)
|
|||||||
d = d_ptr.loadAcquire();
|
d = d_ptr.loadAcquire();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
return d->lockForWrite(timeout);
|
return d->lockForWrite(lock, timeout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -418,7 +424,7 @@ void QReadWriteLock::unlock()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMutexLocker locker(&d->mutex);
|
const auto lock = qt_scoped_lock(d->mutex);
|
||||||
if (d->writerCount) {
|
if (d->writerCount) {
|
||||||
Q_ASSERT(d->writerCount == 1);
|
Q_ASSERT(d->writerCount == 1);
|
||||||
Q_ASSERT(d->readerCount == 0);
|
Q_ASSERT(d->readerCount == 0);
|
||||||
@ -460,9 +466,9 @@ QReadWriteLock::StateForWaitCondition QReadWriteLock::stateForWaitCondition() co
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QReadWriteLockPrivate::lockForRead(int timeout)
|
bool QReadWriteLockPrivate::lockForRead(std::unique_lock<std::mutex> &lock, int timeout)
|
||||||
{
|
{
|
||||||
Q_ASSERT(!mutex.tryLock()); // mutex must be locked when entering this function
|
Q_ASSERT(!mutex.try_lock()); // mutex must be locked when entering this function
|
||||||
|
|
||||||
QElapsedTimer t;
|
QElapsedTimer t;
|
||||||
if (timeout > 0)
|
if (timeout > 0)
|
||||||
@ -476,10 +482,10 @@ bool QReadWriteLockPrivate::lockForRead(int timeout)
|
|||||||
if (elapsed > timeout)
|
if (elapsed > timeout)
|
||||||
return false;
|
return false;
|
||||||
waitingReaders++;
|
waitingReaders++;
|
||||||
readerCond.wait(&mutex, timeout - elapsed);
|
readerCond.wait_for(lock, ms{timeout - elapsed});
|
||||||
} else {
|
} else {
|
||||||
waitingReaders++;
|
waitingReaders++;
|
||||||
readerCond.wait(&mutex);
|
readerCond.wait(lock);
|
||||||
}
|
}
|
||||||
waitingReaders--;
|
waitingReaders--;
|
||||||
}
|
}
|
||||||
@ -488,9 +494,9 @@ bool QReadWriteLockPrivate::lockForRead(int timeout)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QReadWriteLockPrivate::lockForWrite(int timeout)
|
bool QReadWriteLockPrivate::lockForWrite(std::unique_lock<std::mutex> &lock, int timeout)
|
||||||
{
|
{
|
||||||
Q_ASSERT(!mutex.tryLock()); // mutex must be locked when entering this function
|
Q_ASSERT(!mutex.try_lock()); // mutex must be locked when entering this function
|
||||||
|
|
||||||
QElapsedTimer t;
|
QElapsedTimer t;
|
||||||
if (timeout > 0)
|
if (timeout > 0)
|
||||||
@ -505,15 +511,15 @@ bool QReadWriteLockPrivate::lockForWrite(int timeout)
|
|||||||
if (waitingReaders && !waitingWriters && !writerCount) {
|
if (waitingReaders && !waitingWriters && !writerCount) {
|
||||||
// We timed out and now there is no more writers or waiting writers, but some
|
// We timed out and now there is no more writers or waiting writers, but some
|
||||||
// readers were queueud (probably because of us). Wake the waiting readers.
|
// readers were queueud (probably because of us). Wake the waiting readers.
|
||||||
readerCond.wakeAll();
|
readerCond.notify_all();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
waitingWriters++;
|
waitingWriters++;
|
||||||
writerCond.wait(&mutex, timeout - elapsed);
|
writerCond.wait_for(lock, ms{timeout - elapsed});
|
||||||
} else {
|
} else {
|
||||||
waitingWriters++;
|
waitingWriters++;
|
||||||
writerCond.wait(&mutex);
|
writerCond.wait(lock);
|
||||||
}
|
}
|
||||||
waitingWriters--;
|
waitingWriters--;
|
||||||
}
|
}
|
||||||
@ -526,17 +532,17 @@ bool QReadWriteLockPrivate::lockForWrite(int timeout)
|
|||||||
|
|
||||||
void QReadWriteLockPrivate::unlock()
|
void QReadWriteLockPrivate::unlock()
|
||||||
{
|
{
|
||||||
Q_ASSERT(!mutex.tryLock()); // mutex must be locked when entering this function
|
Q_ASSERT(!mutex.try_lock()); // mutex must be locked when entering this function
|
||||||
if (waitingWriters)
|
if (waitingWriters)
|
||||||
writerCond.wakeOne();
|
writerCond.notify_one();
|
||||||
else if (waitingReaders)
|
else if (waitingReaders)
|
||||||
readerCond.wakeAll();
|
readerCond.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QReadWriteLockPrivate::recursiveLockForRead(int timeout)
|
bool QReadWriteLockPrivate::recursiveLockForRead(int timeout)
|
||||||
{
|
{
|
||||||
Q_ASSERT(recursive);
|
Q_ASSERT(recursive);
|
||||||
QMutexLocker lock(&mutex);
|
auto lock = qt_unique_lock(mutex);
|
||||||
|
|
||||||
Qt::HANDLE self = QThread::currentThreadId();
|
Qt::HANDLE self = QThread::currentThreadId();
|
||||||
|
|
||||||
@ -546,7 +552,7 @@ bool QReadWriteLockPrivate::recursiveLockForRead(int timeout)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!lockForRead(timeout))
|
if (!lockForRead(lock, timeout))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
currentReaders.insert(self, 1);
|
currentReaders.insert(self, 1);
|
||||||
@ -556,7 +562,7 @@ bool QReadWriteLockPrivate::recursiveLockForRead(int timeout)
|
|||||||
bool QReadWriteLockPrivate::recursiveLockForWrite(int timeout)
|
bool QReadWriteLockPrivate::recursiveLockForWrite(int timeout)
|
||||||
{
|
{
|
||||||
Q_ASSERT(recursive);
|
Q_ASSERT(recursive);
|
||||||
QMutexLocker lock(&mutex);
|
auto lock = qt_unique_lock(mutex);
|
||||||
|
|
||||||
Qt::HANDLE self = QThread::currentThreadId();
|
Qt::HANDLE self = QThread::currentThreadId();
|
||||||
if (currentWriter == self) {
|
if (currentWriter == self) {
|
||||||
@ -564,7 +570,7 @@ bool QReadWriteLockPrivate::recursiveLockForWrite(int timeout)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!lockForWrite(timeout))
|
if (!lockForWrite(lock, timeout))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
currentWriter = self;
|
currentWriter = self;
|
||||||
@ -574,7 +580,7 @@ bool QReadWriteLockPrivate::recursiveLockForWrite(int timeout)
|
|||||||
void QReadWriteLockPrivate::recursiveUnlock()
|
void QReadWriteLockPrivate::recursiveUnlock()
|
||||||
{
|
{
|
||||||
Q_ASSERT(recursive);
|
Q_ASSERT(recursive);
|
||||||
QMutexLocker lock(&mutex);
|
auto lock = qt_unique_lock(mutex);
|
||||||
|
|
||||||
Qt::HANDLE self = QThread::currentThreadId();
|
Qt::HANDLE self = QThread::currentThreadId();
|
||||||
if (self == currentWriter) {
|
if (self == currentWriter) {
|
||||||
|
@ -54,7 +54,9 @@
|
|||||||
|
|
||||||
#include <QtCore/private/qglobal_p.h>
|
#include <QtCore/private/qglobal_p.h>
|
||||||
#include <QtCore/qhash.h>
|
#include <QtCore/qhash.h>
|
||||||
#include <QtCore/qwaitcondition.h>
|
|
||||||
|
#include <mutex>
|
||||||
|
#include <condition_variable>
|
||||||
|
|
||||||
QT_REQUIRE_CONFIG(thread);
|
QT_REQUIRE_CONFIG(thread);
|
||||||
|
|
||||||
@ -63,38 +65,36 @@ QT_BEGIN_NAMESPACE
|
|||||||
class QReadWriteLockPrivate
|
class QReadWriteLockPrivate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QReadWriteLockPrivate(bool isRecursive = false)
|
explicit QReadWriteLockPrivate(bool isRecursive = false)
|
||||||
: readerCount(0), writerCount(0), waitingReaders(0), waitingWriters(0),
|
: recursive(isRecursive) {}
|
||||||
recursive(isRecursive), id(0), currentWriter(nullptr) {}
|
|
||||||
|
|
||||||
QMutex mutex;
|
std::mutex mutex;
|
||||||
QWaitCondition writerCond;
|
std::condition_variable writerCond;
|
||||||
QWaitCondition readerCond;
|
std::condition_variable readerCond;
|
||||||
int readerCount;
|
int readerCount = 0;
|
||||||
int writerCount;
|
int writerCount = 0;
|
||||||
int waitingReaders;
|
int waitingReaders = 0;
|
||||||
int waitingWriters;
|
int waitingWriters = 0;
|
||||||
const bool recursive;
|
const bool recursive;
|
||||||
|
|
||||||
//Called with the mutex locked
|
//Called with the mutex locked
|
||||||
bool lockForWrite(int timeout);
|
bool lockForWrite(std::unique_lock<std::mutex> &lock, int timeout);
|
||||||
bool lockForRead(int timeout);
|
bool lockForRead(std::unique_lock<std::mutex> &lock, int timeout);
|
||||||
void unlock();
|
void unlock();
|
||||||
|
|
||||||
//memory management
|
//memory management
|
||||||
int id;
|
int id = 0;
|
||||||
void release();
|
void release();
|
||||||
static QReadWriteLockPrivate *allocate();
|
static QReadWriteLockPrivate *allocate();
|
||||||
|
|
||||||
// Recusive mutex handling
|
// Recusive mutex handling
|
||||||
Qt::HANDLE currentWriter;
|
Qt::HANDLE currentWriter = {};
|
||||||
QHash<Qt::HANDLE, int> currentReaders;
|
QHash<Qt::HANDLE, int> currentReaders;
|
||||||
|
|
||||||
// called with the mutex unlocked
|
// called with the mutex unlocked
|
||||||
bool recursiveLockForWrite(int timeout);
|
bool recursiveLockForWrite(int timeout);
|
||||||
bool recursiveLockForRead(int timeout);
|
bool recursiveLockForRead(int timeout);
|
||||||
void recursiveUnlock();
|
void recursiveUnlock();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -3432,15 +3432,15 @@ inline qint64 QDateTimePrivate::zoneMSecsToEpochMSecs(qint64 zoneMSecs, const QT
|
|||||||
datetime by adding a number of seconds, days, months, or years.
|
datetime by adding a number of seconds, days, months, or years.
|
||||||
|
|
||||||
QDateTime can describe datetimes with respect to \l{Qt::LocalTime}{local
|
QDateTime can describe datetimes with respect to \l{Qt::LocalTime}{local
|
||||||
time}, to \l{Qt::UTC}{UTC}, to a specified \l{Qt::OffsetFromUTC}{offset
|
time}, to \l{Qt::UTC}{UTC}, to a specified \l{Qt::OffsetFromUTC}{offset from
|
||||||
from UTC} or to a specified \l{Qt::TimeZone}{time zone}, in conjunction
|
UTC} or to a specified \l{Qt::TimeZone}{time zone}, in conjunction with the
|
||||||
with the QTimeZone class. For example, a time zone of "Europe/Berlin" will
|
QTimeZone class. For example, a time zone of "Europe/Berlin" will apply the
|
||||||
apply the daylight-saving rules as used in Germany since 1970. In contrast,
|
daylight-saving rules as used in Germany since 1970. In contrast, an offset
|
||||||
an offset from UTC of +3600 seconds is one hour ahead of UTC (usually
|
from UTC of +3600 seconds is one hour ahead of UTC (usually written in ISO
|
||||||
written in ISO standard notation as "UTC+01:00"), with no daylight-saving
|
standard notation as "UTC+01:00"), with no daylight-saving offset or
|
||||||
offset or changes. When using either local time or a specified time zone,
|
changes. When using either local time or a specified time zone, time-zone
|
||||||
time-zone transitions such as the starts and ends of daylight-saving time
|
transitions such as the starts and ends of daylight-saving time (DST; but
|
||||||
(DST) are taken into account. The choice of system used to represent a
|
see below) are taken into account. The choice of system used to represent a
|
||||||
datetime is described as its "timespec".
|
datetime is described as its "timespec".
|
||||||
|
|
||||||
A QDateTime object is typically created either by giving a date and time
|
A QDateTime object is typically created either by giving a date and time
|
||||||
@ -3528,11 +3528,13 @@ inline qint64 QDateTimePrivate::zoneMSecsToEpochMSecs(qint64 zoneMSecs, const QT
|
|||||||
|
|
||||||
The range of valid dates taking DST into account is 1970-01-01 to the
|
The range of valid dates taking DST into account is 1970-01-01 to the
|
||||||
present, and rules are in place for handling DST correctly until 2037-12-31,
|
present, and rules are in place for handling DST correctly until 2037-12-31,
|
||||||
but these could change. For dates falling outside that range, QDateTime
|
but these could change. For dates after 2037, QDateTime makes a \e{best
|
||||||
makes a \e{best guess} using the rules for year 1970 or 2037, but we can't
|
guess} using the rules for year 2037, but we can't guarantee accuracy;
|
||||||
guarantee accuracy. This means QDateTime doesn't take into account changes
|
indeed, for \e{any} future date, the time-zone may change its rules before
|
||||||
in a time zone before 1970, even if the system's time zone database provides
|
that date comes around. For dates before 1970, QDateTime doesn't take DST
|
||||||
that information.
|
changes into account, even if the system's time zone database provides that
|
||||||
|
information, although it does take into account changes to the time-zone's
|
||||||
|
standard offset, where this information is available.
|
||||||
|
|
||||||
\section2 Offsets From UTC
|
\section2 Offsets From UTC
|
||||||
|
|
||||||
@ -3797,17 +3799,22 @@ QTimeZone QDateTime::timeZone() const
|
|||||||
/*!
|
/*!
|
||||||
\since 5.2
|
\since 5.2
|
||||||
|
|
||||||
Returns the current Offset From UTC in seconds.
|
Returns this date-time's Offset From UTC in seconds.
|
||||||
|
|
||||||
If the timeSpec() is Qt::OffsetFromUTC this will be the value originally set.
|
The result depends on timeSpec():
|
||||||
|
\list
|
||||||
|
\li \c Qt::UTC The offset is 0.
|
||||||
|
\li \c Qt::OffsetFromUTC The offset is the value originally set.
|
||||||
|
\li \c Qt::LocalTime The local time's offset from UTC is returned.
|
||||||
|
\li \c Qt::TimeZone The offset used by the time-zone is returned.
|
||||||
|
\endlist
|
||||||
|
|
||||||
If the timeSpec() is Qt::TimeZone this will be the offset effective in the
|
For the last two, the offset at this date and time will be returned, taking
|
||||||
Time Zone including any Daylight-Saving Offset.
|
account of Daylight-Saving Offset unless the date precedes the start of
|
||||||
|
1970. The offset is the difference between the local time or time in the
|
||||||
If the timeSpec() is Qt::LocalTime this will be the difference between the
|
given time-zone and UTC time; it is positive in time-zones ahead of UTC
|
||||||
Local Time and UTC including any Daylight-Saving Offset.
|
(East of The Prime Meridian), negative for those behind UTC (West of The
|
||||||
|
Prime Meridian).
|
||||||
If the timeSpec() is Qt::UTC this will be 0.
|
|
||||||
|
|
||||||
\sa setOffsetFromUtc()
|
\sa setOffsetFromUtc()
|
||||||
*/
|
*/
|
||||||
|
@ -371,6 +371,7 @@ QDate calculateTransitionLocalDate(const SYSTEMTIME &rule, int year)
|
|||||||
// Otherwise, the rule date is annual and relative:
|
// Otherwise, the rule date is annual and relative:
|
||||||
const int dayOfWeek = rule.wDayOfWeek == 0 ? 7 : rule.wDayOfWeek;
|
const int dayOfWeek = rule.wDayOfWeek == 0 ? 7 : rule.wDayOfWeek;
|
||||||
QDate date(year, rule.wMonth, 1);
|
QDate date(year, rule.wMonth, 1);
|
||||||
|
Q_ASSERT(date.isValid());
|
||||||
// How many days before was last dayOfWeek before target month ?
|
// How many days before was last dayOfWeek before target month ?
|
||||||
int adjust = dayOfWeek - date.dayOfWeek(); // -6 <= adjust < 7
|
int adjust = dayOfWeek - date.dayOfWeek(); // -6 <= adjust < 7
|
||||||
if (adjust >= 0) // Ensure -7 <= adjust < 0:
|
if (adjust >= 0) // Ensure -7 <= adjust < 0:
|
||||||
@ -401,6 +402,7 @@ qint64 calculateTransitionForYear(const SYSTEMTIME &rule, int year, int bias)
|
|||||||
{
|
{
|
||||||
// TODO Consider caching the calculated values - i.e. replace SYSTEMTIME in
|
// TODO Consider caching the calculated values - i.e. replace SYSTEMTIME in
|
||||||
// WinTransitionRule; do this in init() once and store the results.
|
// WinTransitionRule; do this in init() once and store the results.
|
||||||
|
Q_ASSERT(year);
|
||||||
const QDate date = calculateTransitionLocalDate(rule, year);
|
const QDate date = calculateTransitionLocalDate(rule, year);
|
||||||
const QTime time = QTime(rule.wHour, rule.wMinute, rule.wSecond);
|
const QTime time = QTime(rule.wHour, rule.wMinute, rule.wSecond);
|
||||||
if (date.isValid() && time.isValid())
|
if (date.isValid() && time.isValid())
|
||||||
@ -479,6 +481,7 @@ struct TransitionTimePair
|
|||||||
|
|
||||||
int yearEndOffset(const QWinTimeZonePrivate::QWinTransitionRule &rule, int year)
|
int yearEndOffset(const QWinTimeZonePrivate::QWinTransitionRule &rule, int year)
|
||||||
{
|
{
|
||||||
|
Q_ASSERT(year);
|
||||||
int offset = rule.standardTimeBias;
|
int offset = rule.standardTimeBias;
|
||||||
// Only needed to help another TransitionTimePair work out year + 1's start
|
// Only needed to help another TransitionTimePair work out year + 1's start
|
||||||
// offset; and the oldYearOffset we use only affects an alleged transition
|
// offset; and the oldYearOffset we use only affects an alleged transition
|
||||||
@ -743,11 +746,12 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::data(qint64 forMSecsSinceEpoch) cons
|
|||||||
const QWinTransitionRule &rule = m_tranRules.at(ruleIndex);
|
const QWinTransitionRule &rule = m_tranRules.at(ruleIndex);
|
||||||
// Does this rule's period include any transition at all ?
|
// Does this rule's period include any transition at all ?
|
||||||
if (rule.standardTimeRule.wMonth > 0 || rule.daylightTimeRule.wMonth > 0) {
|
if (rule.standardTimeRule.wMonth > 0 || rule.daylightTimeRule.wMonth > 0) {
|
||||||
const int endYear = qMax(rule.startYear, year - 1);
|
int prior = year == 1 ? -1 : year - 1; // No year 0.
|
||||||
|
const int endYear = qMax(rule.startYear, prior);
|
||||||
while (year >= endYear) {
|
while (year >= endYear) {
|
||||||
const int newYearOffset = (year <= rule.startYear && ruleIndex > 0)
|
const int newYearOffset = (year <= rule.startYear && ruleIndex > 0)
|
||||||
? yearEndOffset(m_tranRules.at(ruleIndex - 1), year - 1)
|
? yearEndOffset(m_tranRules.at(ruleIndex - 1), prior)
|
||||||
: yearEndOffset(rule, year - 1);
|
: yearEndOffset(rule, prior);
|
||||||
const TransitionTimePair pair(rule, year, newYearOffset);
|
const TransitionTimePair pair(rule, year, newYearOffset);
|
||||||
bool isDst = false;
|
bool isDst = false;
|
||||||
if (pair.std != invalidMSecs() && pair.std <= forMSecsSinceEpoch) {
|
if (pair.std != invalidMSecs() && pair.std <= forMSecsSinceEpoch) {
|
||||||
@ -755,7 +759,8 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::data(qint64 forMSecsSinceEpoch) cons
|
|||||||
} else if (pair.dst != invalidMSecs() && pair.dst <= forMSecsSinceEpoch) {
|
} else if (pair.dst != invalidMSecs() && pair.dst <= forMSecsSinceEpoch) {
|
||||||
isDst = true;
|
isDst = true;
|
||||||
} else {
|
} else {
|
||||||
--year; // Try an earlier year for this rule (once).
|
year = prior; // Try an earlier year for this rule (once).
|
||||||
|
prior = year == 1 ? -1 : year - 1; // No year 0.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
return ruleToData(rule, forMSecsSinceEpoch,
|
return ruleToData(rule, forMSecsSinceEpoch,
|
||||||
@ -767,8 +772,11 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::data(qint64 forMSecsSinceEpoch) cons
|
|||||||
// No transition, no DST, use the year's standard time.
|
// No transition, no DST, use the year's standard time.
|
||||||
return ruleToData(rule, forMSecsSinceEpoch, QTimeZone::StandardTime);
|
return ruleToData(rule, forMSecsSinceEpoch, QTimeZone::StandardTime);
|
||||||
}
|
}
|
||||||
if (year >= rule.startYear)
|
if (year >= rule.startYear) {
|
||||||
year = rule.startYear - 1; // Seek last transition in new rule.
|
year = rule.startYear - 1; // Seek last transition in new rule.
|
||||||
|
if (!year)
|
||||||
|
--year;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// We don't have relevant data :-(
|
// We don't have relevant data :-(
|
||||||
return invalidData();
|
return invalidData();
|
||||||
@ -795,9 +803,10 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::nextTransition(qint64 afterMSecsSinc
|
|||||||
year = rule.startYear; // Seek first transition in this rule.
|
year = rule.startYear; // Seek first transition in this rule.
|
||||||
const int endYear = ruleIndex + 1 < m_tranRules.count()
|
const int endYear = ruleIndex + 1 < m_tranRules.count()
|
||||||
? qMin(m_tranRules.at(ruleIndex + 1).startYear, year + 2) : (year + 2);
|
? qMin(m_tranRules.at(ruleIndex + 1).startYear, year + 2) : (year + 2);
|
||||||
|
int prior = year == 1 ? -1 : year - 1; // No year 0.
|
||||||
int newYearOffset = (year <= rule.startYear && ruleIndex > 0)
|
int newYearOffset = (year <= rule.startYear && ruleIndex > 0)
|
||||||
? yearEndOffset(m_tranRules.at(ruleIndex - 1), year - 1)
|
? yearEndOffset(m_tranRules.at(ruleIndex - 1), prior)
|
||||||
: yearEndOffset(rule, year - 1);
|
: yearEndOffset(rule, prior);
|
||||||
while (year < endYear) {
|
while (year < endYear) {
|
||||||
const TransitionTimePair pair(rule, year, newYearOffset);
|
const TransitionTimePair pair(rule, year, newYearOffset);
|
||||||
bool isDst = false;
|
bool isDst = false;
|
||||||
@ -810,7 +819,9 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::nextTransition(qint64 afterMSecsSinc
|
|||||||
newYearOffset = rule.standardTimeBias;
|
newYearOffset = rule.standardTimeBias;
|
||||||
if (pair.dst > pair.std)
|
if (pair.dst > pair.std)
|
||||||
newYearOffset += rule.daylightTimeBias;
|
newYearOffset += rule.daylightTimeBias;
|
||||||
++year; // Try a later year for this rule (once).
|
// Try a later year for this rule (once).
|
||||||
|
prior = year;
|
||||||
|
year = year == -1 ? 1 : year + 1; // No year 0
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -837,11 +848,12 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::previousTransition(qint64 beforeMSec
|
|||||||
const QWinTransitionRule &rule = m_tranRules.at(ruleIndex);
|
const QWinTransitionRule &rule = m_tranRules.at(ruleIndex);
|
||||||
// Does this rule's period include any transition at all ?
|
// Does this rule's period include any transition at all ?
|
||||||
if (rule.standardTimeRule.wMonth > 0 || rule.daylightTimeRule.wMonth > 0) {
|
if (rule.standardTimeRule.wMonth > 0 || rule.daylightTimeRule.wMonth > 0) {
|
||||||
const int endYear = qMax(rule.startYear, year - 1);
|
int prior = year == 1 ? -1 : year - 1; // No year 0.
|
||||||
|
const int endYear = qMax(rule.startYear, prior);
|
||||||
while (year >= endYear) {
|
while (year >= endYear) {
|
||||||
const int newYearOffset = (year <= rule.startYear && ruleIndex > 0)
|
const int newYearOffset = (year <= rule.startYear && ruleIndex > 0)
|
||||||
? yearEndOffset(m_tranRules.at(ruleIndex - 1), year - 1)
|
? yearEndOffset(m_tranRules.at(ruleIndex - 1), prior)
|
||||||
: yearEndOffset(rule, year - 1);
|
: yearEndOffset(rule, prior);
|
||||||
const TransitionTimePair pair(rule, year, newYearOffset);
|
const TransitionTimePair pair(rule, year, newYearOffset);
|
||||||
bool isDst = false;
|
bool isDst = false;
|
||||||
if (pair.std != invalidMSecs() && pair.std < beforeMSecsSinceEpoch) {
|
if (pair.std != invalidMSecs() && pair.std < beforeMSecsSinceEpoch) {
|
||||||
@ -849,7 +861,8 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::previousTransition(qint64 beforeMSec
|
|||||||
} else if (pair.dst != invalidMSecs() && pair.dst < beforeMSecsSinceEpoch) {
|
} else if (pair.dst != invalidMSecs() && pair.dst < beforeMSecsSinceEpoch) {
|
||||||
isDst = true;
|
isDst = true;
|
||||||
} else {
|
} else {
|
||||||
--year; // Try an earlier year for this rule (once).
|
year = prior; // Try an earlier year for this rule (once).
|
||||||
|
prior = year == 1 ? -1 : year - 1; // No year 0.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (isDst)
|
if (isDst)
|
||||||
@ -863,8 +876,11 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::previousTransition(qint64 beforeMSec
|
|||||||
// rule:
|
// rule:
|
||||||
return ruleToData(rule, startOfTime, QTimeZone::StandardTime, false);
|
return ruleToData(rule, startOfTime, QTimeZone::StandardTime, false);
|
||||||
} // else: no transition during rule's period
|
} // else: no transition during rule's period
|
||||||
if (year >= rule.startYear)
|
if (year >= rule.startYear) {
|
||||||
year = rule.startYear - 1; // Seek last transition in new rule
|
year = rule.startYear - 1; // Seek last transition in new rule
|
||||||
|
if (!year)
|
||||||
|
--year;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Apparently no transition before the given time:
|
// Apparently no transition before the given time:
|
||||||
return invalidData();
|
return invalidData();
|
||||||
|
@ -150,7 +150,7 @@
|
|||||||
// factory loader
|
// factory loader
|
||||||
#include <qcoreapplication.h>
|
#include <qcoreapplication.h>
|
||||||
#include <private/qfactoryloader_p.h>
|
#include <private/qfactoryloader_p.h>
|
||||||
#include <QMutexLocker>
|
#include <QtCore/private/qlocking_p.h>
|
||||||
|
|
||||||
// for qt_getImageText
|
// for qt_getImageText
|
||||||
#include <private/qimage_p.h>
|
#include <private/qimage_p.h>
|
||||||
@ -186,8 +186,8 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
|
|||||||
QByteArray suffix;
|
QByteArray suffix;
|
||||||
|
|
||||||
#ifndef QT_NO_IMAGEFORMATPLUGIN
|
#ifndef QT_NO_IMAGEFORMATPLUGIN
|
||||||
static QMutex mutex;
|
static QBasicMutex mutex;
|
||||||
QMutexLocker locker(&mutex);
|
const auto locker = qt_scoped_lock(mutex);
|
||||||
|
|
||||||
typedef QMultiMap<int, QString> PluginKeyMap;
|
typedef QMultiMap<int, QString> PluginKeyMap;
|
||||||
|
|
||||||
|
@ -57,6 +57,7 @@
|
|||||||
#include "qregexp.h"
|
#include "qregexp.h"
|
||||||
#include "qregion.h"
|
#include "qregion.h"
|
||||||
#include "qdebug.h"
|
#include "qdebug.h"
|
||||||
|
#include <QtCore/private/qlocking_p.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
@ -1427,7 +1428,7 @@ void qt_init_picture_plugins()
|
|||||||
typedef PluginKeyMap::const_iterator PluginKeyMapConstIterator;
|
typedef PluginKeyMap::const_iterator PluginKeyMapConstIterator;
|
||||||
|
|
||||||
static QBasicMutex mutex;
|
static QBasicMutex mutex;
|
||||||
QMutexLocker locker(&mutex);
|
const auto locker = qt_scoped_lock(mutex);
|
||||||
static QFactoryLoader loader(QPictureFormatInterface_iid,
|
static QFactoryLoader loader(QPictureFormatInterface_iid,
|
||||||
QStringLiteral("/pictureformats"));
|
QStringLiteral("/pictureformats"));
|
||||||
|
|
||||||
|
@ -58,6 +58,7 @@
|
|||||||
#include <QtCore/private/qabstracteventdispatcher_p.h>
|
#include <QtCore/private/qabstracteventdispatcher_p.h>
|
||||||
#include <QtCore/qmutex.h>
|
#include <QtCore/qmutex.h>
|
||||||
#include <QtCore/private/qthread_p.h>
|
#include <QtCore/private/qthread_p.h>
|
||||||
|
#include <QtCore/private/qlocking_p.h>
|
||||||
#include <QtCore/qdir.h>
|
#include <QtCore/qdir.h>
|
||||||
#include <QtCore/qlibraryinfo.h>
|
#include <QtCore/qlibraryinfo.h>
|
||||||
#include <QtCore/qnumeric.h>
|
#include <QtCore/qnumeric.h>
|
||||||
@ -3305,7 +3306,7 @@ void QGuiApplicationPrivate::applyWindowGeometrySpecificationTo(QWindow *window)
|
|||||||
QFont QGuiApplication::font()
|
QFont QGuiApplication::font()
|
||||||
{
|
{
|
||||||
Q_ASSERT_X(QGuiApplicationPrivate::self, "QGuiApplication::font()", "no QGuiApplication instance");
|
Q_ASSERT_X(QGuiApplicationPrivate::self, "QGuiApplication::font()", "no QGuiApplication instance");
|
||||||
QMutexLocker locker(&applicationFontMutex);
|
const auto locker = qt_scoped_lock(applicationFontMutex);
|
||||||
initFontUnlocked();
|
initFontUnlocked();
|
||||||
return *QGuiApplicationPrivate::app_font;
|
return *QGuiApplicationPrivate::app_font;
|
||||||
}
|
}
|
||||||
@ -3317,7 +3318,7 @@ QFont QGuiApplication::font()
|
|||||||
*/
|
*/
|
||||||
void QGuiApplication::setFont(const QFont &font)
|
void QGuiApplication::setFont(const QFont &font)
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&applicationFontMutex);
|
auto locker = qt_unique_lock(applicationFontMutex);
|
||||||
const bool emitChange = !QGuiApplicationPrivate::app_font
|
const bool emitChange = !QGuiApplicationPrivate::app_font
|
||||||
|| (*QGuiApplicationPrivate::app_font != font);
|
|| (*QGuiApplicationPrivate::app_font != font);
|
||||||
if (!QGuiApplicationPrivate::app_font)
|
if (!QGuiApplicationPrivate::app_font)
|
||||||
@ -4081,7 +4082,7 @@ void QGuiApplicationPrivate::notifyThemeChanged()
|
|||||||
sendApplicationPaletteChange();
|
sendApplicationPaletteChange();
|
||||||
}
|
}
|
||||||
if (!(applicationResourceFlags & ApplicationFontExplicitlySet)) {
|
if (!(applicationResourceFlags & ApplicationFontExplicitlySet)) {
|
||||||
QMutexLocker locker(&applicationFontMutex);
|
const auto locker = qt_scoped_lock(applicationFontMutex);
|
||||||
clearFontUnlocked();
|
clearFontUnlocked();
|
||||||
initFontUnlocked();
|
initFontUnlocked();
|
||||||
}
|
}
|
||||||
|
@ -680,8 +680,11 @@ QDpi QHighDpiScaling::logicalDpi(const QScreen *screen)
|
|||||||
if (!screen || !screen->handle())
|
if (!screen || !screen->handle())
|
||||||
return QDpi(96, 96);
|
return QDpi(96, 96);
|
||||||
|
|
||||||
if (!m_usePixelDensity)
|
if (!m_usePixelDensity) {
|
||||||
return QPlatformScreen::overrideDpi(screen->handle()->logicalDpi());
|
const qreal screenScaleFactor = screenSubfactor(screen->handle());
|
||||||
|
const QDpi dpi = QPlatformScreen::overrideDpi(screen->handle()->logicalDpi());
|
||||||
|
return QDpi{ dpi.first / screenScaleFactor, dpi.second / screenScaleFactor };
|
||||||
|
}
|
||||||
|
|
||||||
const qreal scaleFactor = rawScaleFactor(screen->handle());
|
const qreal scaleFactor = rawScaleFactor(screen->handle());
|
||||||
const qreal roundedScaleFactor = roundScaleFactor(scaleFactor);
|
const qreal roundedScaleFactor = roundScaleFactor(scaleFactor);
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
|
|
||||||
#include <QtCore/QThreadStorage>
|
#include <QtCore/QThreadStorage>
|
||||||
#include <QtCore/QThread>
|
#include <QtCore/QThread>
|
||||||
|
#include <QtCore/private/qlocking_p.h>
|
||||||
|
|
||||||
#include <QtGui/private/qguiapplication_p.h>
|
#include <QtGui/private/qguiapplication_p.h>
|
||||||
#include <QtGui/private/qopengl_p.h>
|
#include <QtGui/private/qopengl_p.h>
|
||||||
@ -1442,7 +1443,7 @@ QOpenGLContextGroup *QOpenGLContextGroup::currentContextGroup()
|
|||||||
|
|
||||||
void QOpenGLContextGroupPrivate::addContext(QOpenGLContext *ctx)
|
void QOpenGLContextGroupPrivate::addContext(QOpenGLContext *ctx)
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&m_mutex);
|
const auto locker = qt_scoped_lock(m_mutex);
|
||||||
m_refs.ref();
|
m_refs.ref();
|
||||||
m_shares << ctx;
|
m_shares << ctx;
|
||||||
}
|
}
|
||||||
@ -1454,7 +1455,7 @@ void QOpenGLContextGroupPrivate::removeContext(QOpenGLContext *ctx)
|
|||||||
bool deleteObject = false;
|
bool deleteObject = false;
|
||||||
|
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&m_mutex);
|
const auto locker = qt_scoped_lock(m_mutex);
|
||||||
m_shares.removeOne(ctx);
|
m_shares.removeOne(ctx);
|
||||||
|
|
||||||
if (ctx == m_context && !m_shares.isEmpty())
|
if (ctx == m_context && !m_shares.isEmpty())
|
||||||
@ -1502,7 +1503,7 @@ void QOpenGLContextGroupPrivate::cleanup()
|
|||||||
|
|
||||||
void QOpenGLContextGroupPrivate::deletePendingResources(QOpenGLContext *ctx)
|
void QOpenGLContextGroupPrivate::deletePendingResources(QOpenGLContext *ctx)
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&m_mutex);
|
const auto locker = qt_scoped_lock(m_mutex);
|
||||||
|
|
||||||
const QList<QOpenGLSharedResource *> pending = m_pendingDeletion;
|
const QList<QOpenGLSharedResource *> pending = m_pendingDeletion;
|
||||||
m_pendingDeletion.clear();
|
m_pendingDeletion.clear();
|
||||||
@ -1543,7 +1544,7 @@ void QOpenGLContextGroupPrivate::deletePendingResources(QOpenGLContext *ctx)
|
|||||||
QOpenGLSharedResource::QOpenGLSharedResource(QOpenGLContextGroup *group)
|
QOpenGLSharedResource::QOpenGLSharedResource(QOpenGLContextGroup *group)
|
||||||
: m_group(group)
|
: m_group(group)
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&m_group->d_func()->m_mutex);
|
const auto locker = qt_scoped_lock(m_group->d_func()->m_mutex);
|
||||||
m_group->d_func()->m_sharedResources << this;
|
m_group->d_func()->m_sharedResources << this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1559,7 +1560,7 @@ void QOpenGLSharedResource::free()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMutexLocker locker(&m_group->d_func()->m_mutex);
|
const auto locker = qt_scoped_lock(m_group->d_func()->m_mutex);
|
||||||
m_group->d_func()->m_sharedResources.removeOne(this);
|
m_group->d_func()->m_sharedResources.removeOne(this);
|
||||||
m_group->d_func()->m_pendingDeletion << this;
|
m_group->d_func()->m_pendingDeletion << this;
|
||||||
|
|
||||||
|
@ -228,7 +228,7 @@ TouchDevices::TouchDevices()
|
|||||||
*/
|
*/
|
||||||
QList<const QTouchDevice *> QTouchDevice::devices()
|
QList<const QTouchDevice *> QTouchDevice::devices()
|
||||||
{
|
{
|
||||||
QMutexLocker lock(&devicesMutex);
|
const auto locker = qt_scoped_lock(devicesMutex);
|
||||||
return deviceList->list;
|
return deviceList->list;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,13 +237,13 @@ QList<const QTouchDevice *> QTouchDevice::devices()
|
|||||||
*/
|
*/
|
||||||
bool QTouchDevicePrivate::isRegistered(const QTouchDevice *dev)
|
bool QTouchDevicePrivate::isRegistered(const QTouchDevice *dev)
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&devicesMutex);
|
const auto locker = qt_scoped_lock(devicesMutex);
|
||||||
return deviceList->list.contains(dev);
|
return deviceList->list.contains(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
const QTouchDevice *QTouchDevicePrivate::deviceById(quint8 id)
|
const QTouchDevice *QTouchDevicePrivate::deviceById(quint8 id)
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&devicesMutex);
|
const auto locker = qt_scoped_lock(devicesMutex);
|
||||||
for (const QTouchDevice *dev : qAsConst(deviceList->list))
|
for (const QTouchDevice *dev : qAsConst(deviceList->list))
|
||||||
if (QTouchDevicePrivate::get(const_cast<QTouchDevice *>(dev))->id == id)
|
if (QTouchDevicePrivate::get(const_cast<QTouchDevice *>(dev))->id == id)
|
||||||
return dev;
|
return dev;
|
||||||
@ -255,7 +255,7 @@ const QTouchDevice *QTouchDevicePrivate::deviceById(quint8 id)
|
|||||||
*/
|
*/
|
||||||
void QTouchDevicePrivate::registerDevice(const QTouchDevice *dev)
|
void QTouchDevicePrivate::registerDevice(const QTouchDevice *dev)
|
||||||
{
|
{
|
||||||
QMutexLocker lock(&devicesMutex);
|
const auto locker = qt_scoped_lock(devicesMutex);
|
||||||
deviceList->list.append(dev);
|
deviceList->list.append(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,7 +264,7 @@ void QTouchDevicePrivate::registerDevice(const QTouchDevice *dev)
|
|||||||
*/
|
*/
|
||||||
void QTouchDevicePrivate::unregisterDevice(const QTouchDevice *dev)
|
void QTouchDevicePrivate::unregisterDevice(const QTouchDevice *dev)
|
||||||
{
|
{
|
||||||
QMutexLocker lock(&devicesMutex);
|
const auto locker = qt_scoped_lock(devicesMutex);
|
||||||
deviceList->list.removeOne(dev);
|
deviceList->list.removeOne(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,17 +62,16 @@ class QColorVector
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QColorVector() = default;
|
QColorVector() = default;
|
||||||
Q_DECL_CONSTEXPR QColorVector(float x, float y, float z) : x(x), y(y), z(z), _unused(0.0f) { }
|
Q_DECL_CONSTEXPR QColorVector(float x, float y, float z) : x(x), y(y), z(z) { }
|
||||||
explicit Q_DECL_CONSTEXPR QColorVector(const QPointF &chr) // from XY chromaticity
|
explicit Q_DECL_CONSTEXPR QColorVector(const QPointF &chr) // from XY chromaticity
|
||||||
: x(chr.x() / chr.y())
|
: x(chr.x() / chr.y())
|
||||||
, y(1.0f)
|
, y(1.0f)
|
||||||
, z((1.0 - chr.x() - chr.y()) / chr.y())
|
, z((1.0 - chr.x() - chr.y()) / chr.y())
|
||||||
, _unused(0.0f)
|
|
||||||
{ }
|
{ }
|
||||||
float x; // X, x or red
|
float x = 0.0f; // X, x or red
|
||||||
float y; // Y, y or green
|
float y = 0.0f; // Y, y or green
|
||||||
float z; // Z, Y or blue
|
float z = 0.0f; // Z, Y or blue
|
||||||
float _unused;
|
float _unused = 0.0f;
|
||||||
|
|
||||||
friend inline bool operator==(const QColorVector &v1, const QColorVector &v2);
|
friend inline bool operator==(const QColorVector &v1, const QColorVector &v2);
|
||||||
friend inline bool operator!=(const QColorVector &v1, const QColorVector &v2);
|
friend inline bool operator!=(const QColorVector &v1, const QColorVector &v2);
|
||||||
@ -81,7 +80,6 @@ public:
|
|||||||
return !x && !y && !z;
|
return !x && !y && !z;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Q_DECL_CONSTEXPR QColorVector null() { return QColorVector(0.0f, 0.0f, 0.0f); }
|
|
||||||
static bool isValidChromaticity(const QPointF &chr)
|
static bool isValidChromaticity(const QPointF &chr)
|
||||||
{
|
{
|
||||||
if (chr.x() < qreal(0.0) || chr.x() > qreal(1.0))
|
if (chr.x() < qreal(0.0) || chr.x() > qreal(1.0))
|
||||||
@ -187,10 +185,6 @@ public:
|
|||||||
{ r.z, g.z, b.z } };
|
{ r.z, g.z, b.z } };
|
||||||
}
|
}
|
||||||
|
|
||||||
static QColorMatrix null()
|
|
||||||
{
|
|
||||||
return { QColorVector::null(), QColorVector::null(), QColorVector::null() };
|
|
||||||
}
|
|
||||||
static QColorMatrix identity()
|
static QColorMatrix identity()
|
||||||
{
|
{
|
||||||
return { { 1.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f, 1.0f } };
|
return { { 1.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f, 1.0f } };
|
||||||
|
@ -146,17 +146,11 @@ QColorMatrix QColorSpacePrimaries::toXyzMatrix() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
QColorSpacePrivate::QColorSpacePrivate()
|
QColorSpacePrivate::QColorSpacePrivate()
|
||||||
: primaries(QColorSpace::Primaries::Custom)
|
|
||||||
, transferFunction(QColorSpace::TransferFunction::Custom)
|
|
||||||
, gamma(0.0f)
|
|
||||||
, whitePoint(QColorVector::null())
|
|
||||||
, toXyz(QColorMatrix::null())
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
QColorSpacePrivate::QColorSpacePrivate(QColorSpace::NamedColorSpace namedColorSpace)
|
QColorSpacePrivate::QColorSpacePrivate(QColorSpace::NamedColorSpace namedColorSpace)
|
||||||
: namedColorSpace(namedColorSpace)
|
: namedColorSpace(namedColorSpace)
|
||||||
, gamma(0.0f)
|
|
||||||
{
|
{
|
||||||
switch (namedColorSpace) {
|
switch (namedColorSpace) {
|
||||||
case QColorSpace::SRgb:
|
case QColorSpace::SRgb:
|
||||||
@ -282,7 +276,7 @@ void QColorSpacePrivate::initialize()
|
|||||||
void QColorSpacePrivate::setToXyzMatrix()
|
void QColorSpacePrivate::setToXyzMatrix()
|
||||||
{
|
{
|
||||||
if (primaries == QColorSpace::Primaries::Custom) {
|
if (primaries == QColorSpace::Primaries::Custom) {
|
||||||
toXyz = QColorMatrix::null();
|
toXyz = QColorMatrix();
|
||||||
whitePoint = QColorVector::D50();
|
whitePoint = QColorVector::D50();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -124,9 +124,9 @@ public:
|
|||||||
static constexpr QColorSpace::NamedColorSpace Unknown = QColorSpace::NamedColorSpace(0);
|
static constexpr QColorSpace::NamedColorSpace Unknown = QColorSpace::NamedColorSpace(0);
|
||||||
QColorSpace::NamedColorSpace namedColorSpace = Unknown;
|
QColorSpace::NamedColorSpace namedColorSpace = Unknown;
|
||||||
|
|
||||||
QColorSpace::Primaries primaries;
|
QColorSpace::Primaries primaries = QColorSpace::Primaries::Custom;
|
||||||
QColorSpace::TransferFunction transferFunction;
|
QColorSpace::TransferFunction transferFunction = QColorSpace::TransferFunction::Custom;
|
||||||
float gamma;
|
float gamma = 0.0f;
|
||||||
QColorVector whitePoint;
|
QColorVector whitePoint;
|
||||||
|
|
||||||
QColorTrc trc[3];
|
QColorTrc trc[3];
|
||||||
|
@ -612,6 +612,15 @@ static void storeOpaque(QRgba64 *dst, const QRgba64 *src, const QColorVector *bu
|
|||||||
|
|
||||||
static constexpr qsizetype WorkBlockSize = 256;
|
static constexpr qsizetype WorkBlockSize = 256;
|
||||||
|
|
||||||
|
template <typename T, int Count = 1>
|
||||||
|
class QUninitialized
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
operator T*() { return reinterpret_cast<T *>(this); }
|
||||||
|
private:
|
||||||
|
alignas(T) char data[sizeof(T) * Count];
|
||||||
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void QColorTransformPrivate::apply(T *dst, const T *src, qsizetype count, TransformFlags flags) const
|
void QColorTransformPrivate::apply(T *dst, const T *src, qsizetype count, TransformFlags flags) const
|
||||||
{
|
{
|
||||||
@ -623,7 +632,8 @@ void QColorTransformPrivate::apply(T *dst, const T *src, qsizetype count, Transf
|
|||||||
|
|
||||||
bool doApplyMatrix = (colorMatrix != QColorMatrix::identity());
|
bool doApplyMatrix = (colorMatrix != QColorMatrix::identity());
|
||||||
|
|
||||||
QColorVector buffer[WorkBlockSize];
|
QUninitialized<QColorVector, WorkBlockSize> buffer;
|
||||||
|
|
||||||
qsizetype i = 0;
|
qsizetype i = 0;
|
||||||
while (i < count) {
|
while (i < count) {
|
||||||
const qsizetype len = qMin(count - i, WorkBlockSize);
|
const qsizetype len = qMin(count - i, WorkBlockSize);
|
||||||
|
209
src/gui/rhi/cs_tdr.h
Normal file
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
|
visible in external GPU debugging tools will not be available and functions
|
||||||
like QRhiCommandBuffer::debugMarkBegin() will become a no-op. Avoid
|
like QRhiCommandBuffer::debugMarkBegin() will become a no-op. Avoid
|
||||||
enabling in production builds as it may involve a performance penalty.
|
enabling in production builds as it may involve a performance penalty.
|
||||||
|
|
||||||
|
\value PreferSoftwareRenderer Indicates that backends should prefer
|
||||||
|
choosing an adapter or physical device that renders in software on the CPU.
|
||||||
|
For example, with Direct3D there is typically a "Basic Render Driver"
|
||||||
|
adapter available with \c{DXGI_ADAPTER_FLAG_SOFTWARE}. Setting this flag
|
||||||
|
requests the backend to choose that adapter over any other, as long as no
|
||||||
|
specific adapter was forced by other backend-specific means. With Vulkan
|
||||||
|
this maps to preferring physical devices with
|
||||||
|
\c{VK_PHYSICAL_DEVICE_TYPE_CPU}. When not available, or when it is not
|
||||||
|
possible to decide if an adapter/device is software-based, this flag is
|
||||||
|
ignored. It may also be ignored with graphics APIs that have no concept and
|
||||||
|
means of enumerating adapters/devices.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -455,8 +467,8 @@ Q_LOGGING_CATEGORY(QRHI_LOG_INFO, "qt.rhi.general")
|
|||||||
|
|
||||||
\value FrameOpDeviceLost The graphics device was lost. This can be
|
\value FrameOpDeviceLost The graphics device was lost. This can be
|
||||||
recoverable by attempting to repeat the operation (such as, beginFrame())
|
recoverable by attempting to repeat the operation (such as, beginFrame())
|
||||||
and releasing and reinitializing all objects backed by native graphics
|
after releasing and reinitializing all objects backed by native graphics
|
||||||
resources.
|
resources. See isDeviceLost().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -673,7 +685,7 @@ bool operator!=(const QRhiDepthStencilClearValue &a, const QRhiDepthStencilClear
|
|||||||
*/
|
*/
|
||||||
uint qHash(const QRhiDepthStencilClearValue &v, uint seed) Q_DECL_NOTHROW
|
uint qHash(const QRhiDepthStencilClearValue &v, uint seed) Q_DECL_NOTHROW
|
||||||
{
|
{
|
||||||
return seed * (qFloor(v.depthClearValue() * 100) + v.stencilClearValue());
|
return seed * (uint(qFloor(qreal(v.depthClearValue()) * 100)) + v.stencilClearValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef QT_NO_DEBUG_STREAM
|
#ifndef QT_NO_DEBUG_STREAM
|
||||||
@ -768,7 +780,8 @@ bool operator!=(const QRhiViewport &a, const QRhiViewport &b) Q_DECL_NOTHROW
|
|||||||
uint qHash(const QRhiViewport &v, uint seed) Q_DECL_NOTHROW
|
uint qHash(const QRhiViewport &v, uint seed) Q_DECL_NOTHROW
|
||||||
{
|
{
|
||||||
const std::array<float, 4> r = v.viewport();
|
const std::array<float, 4> r = v.viewport();
|
||||||
return seed + r[0] + r[1] + r[2] + r[3] + qFloor(v.minDepth() * 100) + qFloor(v.maxDepth() * 100);
|
return seed + uint(r[0]) + uint(r[1]) + uint(r[2]) + uint(r[3])
|
||||||
|
+ uint(qFloor(qreal(v.minDepth()) * 100)) + uint(qFloor(qreal(v.maxDepth()) * 100));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef QT_NO_DEBUG_STREAM
|
#ifndef QT_NO_DEBUG_STREAM
|
||||||
@ -850,7 +863,7 @@ bool operator!=(const QRhiScissor &a, const QRhiScissor &b) Q_DECL_NOTHROW
|
|||||||
uint qHash(const QRhiScissor &v, uint seed) Q_DECL_NOTHROW
|
uint qHash(const QRhiScissor &v, uint seed) Q_DECL_NOTHROW
|
||||||
{
|
{
|
||||||
const std::array<int, 4> r = v.scissor();
|
const std::array<int, 4> r = v.scissor();
|
||||||
return seed + r[0] + r[1] + r[2] + r[3];
|
return seed + uint(r[0]) + uint(r[1]) + uint(r[2]) + uint(r[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef QT_NO_DEBUG_STREAM
|
#ifndef QT_NO_DEBUG_STREAM
|
||||||
@ -1136,7 +1149,7 @@ bool operator!=(const QRhiVertexInputAttribute &a, const QRhiVertexInputAttribut
|
|||||||
*/
|
*/
|
||||||
uint qHash(const QRhiVertexInputAttribute &v, uint seed) Q_DECL_NOTHROW
|
uint qHash(const QRhiVertexInputAttribute &v, uint seed) Q_DECL_NOTHROW
|
||||||
{
|
{
|
||||||
return seed + v.binding() + v.location() + v.format() + v.offset();
|
return seed + uint(v.binding()) + uint(v.location()) + uint(v.format()) + v.offset();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef QT_NO_DEBUG_STREAM
|
#ifndef QT_NO_DEBUG_STREAM
|
||||||
@ -3001,7 +3014,7 @@ bool operator!=(const QRhiShaderResourceBinding &a, const QRhiShaderResourceBind
|
|||||||
uint qHash(const QRhiShaderResourceBinding &b, uint seed) Q_DECL_NOTHROW
|
uint qHash(const QRhiShaderResourceBinding &b, uint seed) Q_DECL_NOTHROW
|
||||||
{
|
{
|
||||||
const char *u = reinterpret_cast<const char *>(&b.d->u);
|
const char *u = reinterpret_cast<const char *>(&b.d->u);
|
||||||
return seed + b.d->binding + 10 * b.d->stage + 100 * b.d->type
|
return seed + uint(b.d->binding) + 10 * uint(b.d->stage) + 100 * uint(b.d->type)
|
||||||
+ qHash(QByteArray::fromRawData(u, sizeof(b.d->u)), seed);
|
+ qHash(QByteArray::fromRawData(u, sizeof(b.d->u)), seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3457,10 +3470,18 @@ QRhiResource::Type QRhiGraphicsPipeline::resourceType() const
|
|||||||
Flag values to describe swapchain properties
|
Flag values to describe swapchain properties
|
||||||
|
|
||||||
\value SurfaceHasPreMulAlpha Indicates that the target surface has
|
\value SurfaceHasPreMulAlpha Indicates that the target surface has
|
||||||
transparency with premultiplied alpha.
|
transparency with premultiplied alpha. For example, this is what Qt Quick
|
||||||
|
uses when the alpha channel is enabled on the target QWindow, because the
|
||||||
|
scenegraph rendrerer always outputs fragments with alpha multiplied into
|
||||||
|
the red, green, and blue values. To ensure identical behavior across
|
||||||
|
platforms, always set QSurfaceFormat::alphaBufferSize() to a non-zero value
|
||||||
|
on the target QWindow whenever this flag is set on the swapchain.
|
||||||
|
|
||||||
\value SurfaceHasNonPreMulAlpha Indicates the target surface has
|
\value SurfaceHasNonPreMulAlpha Indicates the target surface has
|
||||||
transparencyt with non-premultiplied alpha.
|
transparency with non-premultiplied alpha. Be aware that this may not be
|
||||||
|
supported on some systems, if the system compositor always expects content
|
||||||
|
with premultiplied alpha. In that case the behavior with this flag set is
|
||||||
|
expected to be equivalent to SurfaceHasPreMulAlpha.
|
||||||
|
|
||||||
\value sRGB Requests to pick an sRGB format for the swapchain and/or its
|
\value sRGB Requests to pick an sRGB format for the swapchain and/or its
|
||||||
render target views, where applicable. Note that this implies that sRGB
|
render target views, where applicable. Note that this implies that sRGB
|
||||||
@ -3823,8 +3844,8 @@ void QRhiImplementation::compressedFormatInfo(QRhiTexture::Format format, const
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const quint32 wblocks = (size.width() + xdim - 1) / xdim;
|
const quint32 wblocks = uint((size.width() + xdim - 1) / xdim);
|
||||||
const quint32 hblocks = (size.height() + ydim - 1) / ydim;
|
const quint32 hblocks = uint((size.height() + ydim - 1) / ydim);
|
||||||
|
|
||||||
if (bpl)
|
if (bpl)
|
||||||
*bpl = wblocks * blockSize;
|
*bpl = wblocks * blockSize;
|
||||||
@ -3880,9 +3901,9 @@ void QRhiImplementation::textureFormatInfo(QRhiTexture::Format format, const QSi
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (bpl)
|
if (bpl)
|
||||||
*bpl = size.width() * bpc;
|
*bpl = uint(size.width()) * bpc;
|
||||||
if (byteSize)
|
if (byteSize)
|
||||||
*byteSize = size.width() * size.height() * bpc;
|
*byteSize = uint(size.width() * size.height()) * bpc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Approximate because it excludes subresource alignment or multisampling.
|
// Approximate because it excludes subresource alignment or multisampling.
|
||||||
@ -3892,12 +3913,12 @@ quint32 QRhiImplementation::approxByteSizeForTexture(QRhiTexture::Format format,
|
|||||||
quint32 approxSize = 0;
|
quint32 approxSize = 0;
|
||||||
for (int level = 0; level < mipCount; ++level) {
|
for (int level = 0; level < mipCount; ++level) {
|
||||||
quint32 byteSize = 0;
|
quint32 byteSize = 0;
|
||||||
const QSize size(qFloor(float(qMax(1, baseSize.width() >> level))),
|
const QSize size(qFloor(qreal(qMax(1, baseSize.width() >> level))),
|
||||||
qFloor(float(qMax(1, baseSize.height() >> level))));
|
qFloor(qreal(qMax(1, baseSize.height() >> level))));
|
||||||
textureFormatInfo(format, size, nullptr, &byteSize);
|
textureFormatInfo(format, size, nullptr, &byteSize);
|
||||||
approxSize += byteSize;
|
approxSize += byteSize;
|
||||||
}
|
}
|
||||||
approxSize *= layerCount;
|
approxSize *= uint(layerCount);
|
||||||
return approxSize;
|
return approxSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5001,10 +5022,17 @@ const QRhiNativeHandles *QRhi::nativeHandles()
|
|||||||
has to ensure external OpenGL code provided by the application can still
|
has to ensure external OpenGL code provided by the application can still
|
||||||
run like it did before with direct usage of OpenGL, as long as the QRhi is
|
run like it did before with direct usage of OpenGL, as long as the QRhi is
|
||||||
using the OpenGL backend.
|
using the OpenGL backend.
|
||||||
|
|
||||||
|
\return false when failed, similarly to QOpenGLContext::makeCurrent(). When
|
||||||
|
the operation failed, isDeviceLost() can be called to determine if there
|
||||||
|
was a loss of context situation. Such a check is equivalent to checking via
|
||||||
|
QOpenGLContext::isValid().
|
||||||
|
|
||||||
|
\sa QOpenGLContext::makeCurrent(), QOpenGLContext::isValid()
|
||||||
*/
|
*/
|
||||||
void QRhi::makeThreadLocalNativeContextCurrent()
|
bool QRhi::makeThreadLocalNativeContextCurrent()
|
||||||
{
|
{
|
||||||
d->makeThreadLocalNativeContextCurrent();
|
return d->makeThreadLocalNativeContextCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -5036,6 +5064,53 @@ void QRhi::releaseCachedResources()
|
|||||||
d->releaseCachedResources();
|
d->releaseCachedResources();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\return true if the graphics device was lost.
|
||||||
|
|
||||||
|
The loss of the device is typically detected in beginFrame(), endFrame() or
|
||||||
|
QRhiSwapChain::buildOrResize(), depending on the backend and the underlying
|
||||||
|
native APIs. The most common is endFrame() because that is where presenting
|
||||||
|
happens. With some backends QRhiSwapChain::buildOrResize() can also fail
|
||||||
|
due to a device loss. Therefore this function is provided as a generic way
|
||||||
|
to check if a device loss was detected by a previous operation.
|
||||||
|
|
||||||
|
When the device is lost, no further operations should be done via the QRhi.
|
||||||
|
Rather, all QRhi resources should be released, followed by destroying the
|
||||||
|
QRhi. A new QRhi can then be attempted to be created. If successful, all
|
||||||
|
graphics resources must be reinitialized. If not, try again later,
|
||||||
|
repeatedly.
|
||||||
|
|
||||||
|
While simple applications may decide to not care about device loss,
|
||||||
|
on the commonly used desktop platforms a device loss can happen
|
||||||
|
due to a variety of reasons, including physically disconnecting the
|
||||||
|
graphics adapter, disabling the device or driver, uninstalling or upgrading
|
||||||
|
the graphics driver, or due to errors that lead to a graphics device reset.
|
||||||
|
Some of these can happen under perfectly normal circumstances as well, for
|
||||||
|
example the upgrade of the graphics driver to a newer version is a common
|
||||||
|
task that can happen at any time while a Qt application is running. Users
|
||||||
|
may very well expect applications to be able to survive this, even when the
|
||||||
|
application is actively using an API like OpenGL or Direct3D.
|
||||||
|
|
||||||
|
Qt's own frameworks built on top of QRhi, such as, Qt Quick, can be
|
||||||
|
expected to handle and take appropriate measures when a device loss occurs.
|
||||||
|
If the data for graphics resources, such as textures and buffers, are still
|
||||||
|
available on the CPU side, such an event may not be noticeable on the
|
||||||
|
application level at all since graphics resources can seamlessly be
|
||||||
|
reinitialized then. However, applications and libraries working directly
|
||||||
|
with QRhi are expected to be prepared to check and handle device loss
|
||||||
|
situations themselves.
|
||||||
|
|
||||||
|
\note With OpenGL, applications may need to opt-in to context reset
|
||||||
|
notifications by setting QSurfaceFormat::ResetNotification on the
|
||||||
|
QOpenGLContext. This is typically done by enabling the flag in
|
||||||
|
QRhiGles2InitParams::format. Keep in mind however that some systems may
|
||||||
|
generate context resets situations even when this flag is not set.
|
||||||
|
*/
|
||||||
|
bool QRhi::isDeviceLost() const
|
||||||
|
{
|
||||||
|
return d->isDeviceLost();
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\return a new graphics pipeline resource.
|
\return a new graphics pipeline resource.
|
||||||
|
|
||||||
@ -5197,7 +5272,17 @@ QRhiSwapChain *QRhi::newSwapChain()
|
|||||||
|
|
||||||
\endlist
|
\endlist
|
||||||
|
|
||||||
\sa endFrame(), beginOffscreenFrame()
|
\return QRhi::FrameOpSuccess on success, or another QRhi::FrameOpResult
|
||||||
|
value on failure. Some of these should be treated as soft, "try again
|
||||||
|
later" type of errors: When QRhi::FrameOpSwapChainOutOfDate is returned,
|
||||||
|
the swapchain is to be resized or updated by calling
|
||||||
|
QRhiSwapChain::buildOrResize(). The application should then attempt to
|
||||||
|
generate a new frame. QRhi::FrameOpDeviceLost means the graphics device is
|
||||||
|
lost but this may also be recoverable by releasing all resources, including
|
||||||
|
the QRhi itself, and then recreating all resources. See isDeviceLost() for
|
||||||
|
further discussion.
|
||||||
|
|
||||||
|
\sa endFrame(), beginOffscreenFrame(), isDeviceLost()
|
||||||
*/
|
*/
|
||||||
QRhi::FrameOpResult QRhi::beginFrame(QRhiSwapChain *swapChain, BeginFrameFlags flags)
|
QRhi::FrameOpResult QRhi::beginFrame(QRhiSwapChain *swapChain, BeginFrameFlags flags)
|
||||||
{
|
{
|
||||||
@ -5222,7 +5307,17 @@ QRhi::FrameOpResult QRhi::beginFrame(QRhiSwapChain *swapChain, BeginFrameFlags f
|
|||||||
Passing QRhi::SkipPresent skips queuing the Present command or calling
|
Passing QRhi::SkipPresent skips queuing the Present command or calling
|
||||||
swapBuffers.
|
swapBuffers.
|
||||||
|
|
||||||
\sa beginFrame()
|
\return QRhi::FrameOpSuccess on success, or another QRhi::FrameOpResult
|
||||||
|
value on failure. Some of these should be treated as soft, "try again
|
||||||
|
later" type of errors: When QRhi::FrameOpSwapChainOutOfDate is returned,
|
||||||
|
the swapchain is to be resized or updated by calling
|
||||||
|
QRhiSwapChain::buildOrResize(). The application should then attempt to
|
||||||
|
generate a new frame. QRhi::FrameOpDeviceLost means the graphics device is
|
||||||
|
lost but this may also be recoverable by releasing all resources, including
|
||||||
|
the QRhi itself, and then recreating all resources. See isDeviceLost() for
|
||||||
|
further discussion.
|
||||||
|
|
||||||
|
\sa beginFrame(), isDeviceLost()
|
||||||
*/
|
*/
|
||||||
QRhi::FrameOpResult QRhi::endFrame(QRhiSwapChain *swapChain, EndFrameFlags flags)
|
QRhi::FrameOpResult QRhi::endFrame(QRhiSwapChain *swapChain, EndFrameFlags flags)
|
||||||
{
|
{
|
||||||
|
@ -1294,7 +1294,8 @@ public:
|
|||||||
|
|
||||||
enum Flag {
|
enum Flag {
|
||||||
EnableProfiling = 1 << 0,
|
EnableProfiling = 1 << 0,
|
||||||
EnableDebugMarkers = 1 << 1
|
EnableDebugMarkers = 1 << 1,
|
||||||
|
PreferSoftwareRenderer = 1 << 2
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS(Flags, Flag)
|
Q_DECLARE_FLAGS(Flags, Flag)
|
||||||
|
|
||||||
@ -1413,7 +1414,7 @@ public:
|
|||||||
int resourceLimit(ResourceLimit limit) const;
|
int resourceLimit(ResourceLimit limit) const;
|
||||||
|
|
||||||
const QRhiNativeHandles *nativeHandles();
|
const QRhiNativeHandles *nativeHandles();
|
||||||
void makeThreadLocalNativeContextCurrent();
|
bool makeThreadLocalNativeContextCurrent();
|
||||||
|
|
||||||
QRhiProfiler *profiler();
|
QRhiProfiler *profiler();
|
||||||
|
|
||||||
@ -1422,6 +1423,8 @@ public:
|
|||||||
|
|
||||||
void releaseCachedResources();
|
void releaseCachedResources();
|
||||||
|
|
||||||
|
bool isDeviceLost() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QRhi();
|
QRhi();
|
||||||
|
|
||||||
|
@ -156,8 +156,9 @@ public:
|
|||||||
virtual int resourceLimit(QRhi::ResourceLimit limit) const = 0;
|
virtual int resourceLimit(QRhi::ResourceLimit limit) const = 0;
|
||||||
virtual const QRhiNativeHandles *nativeHandles() = 0;
|
virtual const QRhiNativeHandles *nativeHandles() = 0;
|
||||||
virtual void sendVMemStatsToProfiler() = 0;
|
virtual void sendVMemStatsToProfiler() = 0;
|
||||||
virtual void makeThreadLocalNativeContextCurrent() = 0;
|
virtual bool makeThreadLocalNativeContextCurrent() = 0;
|
||||||
virtual void releaseCachedResources() = 0;
|
virtual void releaseCachedResources() = 0;
|
||||||
|
virtual bool isDeviceLost() const = 0;
|
||||||
|
|
||||||
bool isCompressedFormat(QRhiTexture::Format format) const;
|
bool isCompressedFormat(QRhiTexture::Format format) const;
|
||||||
void compressedFormatInfo(QRhiTexture::Format format, const QSize &size,
|
void compressedFormatInfo(QRhiTexture::Format format, const QSize &size,
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
|
|
||||||
#include "qrhid3d11_p_p.h"
|
#include "qrhid3d11_p_p.h"
|
||||||
#include "qshader_p.h"
|
#include "qshader_p.h"
|
||||||
|
#include "cs_tdr.h"
|
||||||
#include <QWindow>
|
#include <QWindow>
|
||||||
#include <QOperatingSystemVersion>
|
#include <QOperatingSystemVersion>
|
||||||
#include <qmath.h>
|
#include <qmath.h>
|
||||||
@ -118,10 +119,20 @@ QT_BEGIN_NAMESPACE
|
|||||||
\c{ID3D11Texture2D *}.
|
\c{ID3D11Texture2D *}.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// help mingw with its ancient sdk headers
|
||||||
|
#ifndef DXGI_ADAPTER_FLAG_SOFTWARE
|
||||||
|
#define DXGI_ADAPTER_FLAG_SOFTWARE 2
|
||||||
|
#endif
|
||||||
|
|
||||||
QRhiD3D11::QRhiD3D11(QRhiD3D11InitParams *params, QRhiD3D11NativeHandles *importDevice)
|
QRhiD3D11::QRhiD3D11(QRhiD3D11InitParams *params, QRhiD3D11NativeHandles *importDevice)
|
||||||
: ofr(this)
|
: ofr(this),
|
||||||
|
deviceCurse(this)
|
||||||
{
|
{
|
||||||
debugLayer = params->enableDebugLayer;
|
debugLayer = params->enableDebugLayer;
|
||||||
|
|
||||||
|
deviceCurse.framesToActivate = params->framesUntilKillingDeviceViaTdr;
|
||||||
|
deviceCurse.permanent = params->repeatDeviceKill;
|
||||||
|
|
||||||
importedDevice = importDevice != nullptr;
|
importedDevice = importDevice != nullptr;
|
||||||
if (importedDevice) {
|
if (importedDevice) {
|
||||||
dev = reinterpret_cast<ID3D11Device *>(importDevice->dev);
|
dev = reinterpret_cast<ID3D11Device *>(importDevice->dev);
|
||||||
@ -155,7 +166,7 @@ static QString comErrorMessage(HRESULT hr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class Int>
|
template <class Int>
|
||||||
static inline Int aligned(Int v, Int byteAlign)
|
inline Int aligned(Int v, Int byteAlign)
|
||||||
{
|
{
|
||||||
return (v + byteAlign - 1) & ~(byteAlign - 1);
|
return (v + byteAlign - 1) & ~(byteAlign - 1);
|
||||||
}
|
}
|
||||||
@ -166,7 +177,7 @@ static IDXGIFactory1 *createDXGIFactory2()
|
|||||||
if (QOperatingSystemVersion::current() > QOperatingSystemVersion::Windows7) {
|
if (QOperatingSystemVersion::current() > QOperatingSystemVersion::Windows7) {
|
||||||
using PtrCreateDXGIFactory2 = HRESULT (WINAPI *)(UINT, REFIID, void **);
|
using PtrCreateDXGIFactory2 = HRESULT (WINAPI *)(UINT, REFIID, void **);
|
||||||
QSystemLibrary dxgilib(QStringLiteral("dxgi"));
|
QSystemLibrary dxgilib(QStringLiteral("dxgi"));
|
||||||
if (auto createDXGIFactory2 = (PtrCreateDXGIFactory2)dxgilib.resolve("CreateDXGIFactory2")) {
|
if (auto createDXGIFactory2 = reinterpret_cast<PtrCreateDXGIFactory2>(dxgilib.resolve("CreateDXGIFactory2"))) {
|
||||||
const HRESULT hr = createDXGIFactory2(0, IID_IDXGIFactory2, reinterpret_cast<void **>(&result));
|
const HRESULT hr = createDXGIFactory2(0, IID_IDXGIFactory2, reinterpret_cast<void **>(&result));
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
qWarning("CreateDXGIFactory2() failed to create DXGI factory: %s", qPrintable(comErrorMessage(hr)));
|
qWarning("CreateDXGIFactory2() failed to create DXGI factory: %s", qPrintable(comErrorMessage(hr)));
|
||||||
@ -221,11 +232,29 @@ bool QRhiD3D11::create(QRhi::Flags flags)
|
|||||||
int requestedAdapterIndex = -1;
|
int requestedAdapterIndex = -1;
|
||||||
if (qEnvironmentVariableIsSet("QT_D3D_ADAPTER_INDEX"))
|
if (qEnvironmentVariableIsSet("QT_D3D_ADAPTER_INDEX"))
|
||||||
requestedAdapterIndex = qEnvironmentVariableIntValue("QT_D3D_ADAPTER_INDEX");
|
requestedAdapterIndex = qEnvironmentVariableIntValue("QT_D3D_ADAPTER_INDEX");
|
||||||
for (int adapterIndex = 0; dxgiFactory->EnumAdapters1(adapterIndex, &adapter) != DXGI_ERROR_NOT_FOUND; ++adapterIndex) {
|
|
||||||
|
if (requestedAdapterIndex < 0 && flags.testFlag(QRhi::PreferSoftwareRenderer)) {
|
||||||
|
for (int adapterIndex = 0; dxgiFactory->EnumAdapters1(UINT(adapterIndex), &adapter) != DXGI_ERROR_NOT_FOUND; ++adapterIndex) {
|
||||||
|
DXGI_ADAPTER_DESC1 desc;
|
||||||
|
adapter->GetDesc1(&desc);
|
||||||
|
adapter->Release();
|
||||||
|
if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) {
|
||||||
|
requestedAdapterIndex = adapterIndex;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int adapterIndex = 0; dxgiFactory->EnumAdapters1(UINT(adapterIndex), &adapter) != DXGI_ERROR_NOT_FOUND; ++adapterIndex) {
|
||||||
DXGI_ADAPTER_DESC1 desc;
|
DXGI_ADAPTER_DESC1 desc;
|
||||||
adapter->GetDesc1(&desc);
|
adapter->GetDesc1(&desc);
|
||||||
const QString name = QString::fromUtf16((char16_t *) desc.Description);
|
const QString name = QString::fromUtf16(reinterpret_cast<char16_t *>(desc.Description));
|
||||||
qCDebug(QRHI_LOG_INFO, "Adapter %d: '%s' (flags 0x%x)", adapterIndex, qPrintable(name), desc.Flags);
|
qCDebug(QRHI_LOG_INFO, "Adapter %d: '%s' (vendor 0x%X device 0x%X flags 0x%X)",
|
||||||
|
adapterIndex,
|
||||||
|
qPrintable(name),
|
||||||
|
desc.VendorId,
|
||||||
|
desc.DeviceId,
|
||||||
|
desc.Flags);
|
||||||
if (!adapterToUse && (requestedAdapterIndex < 0 || requestedAdapterIndex == adapterIndex)) {
|
if (!adapterToUse && (requestedAdapterIndex < 0 || requestedAdapterIndex == adapterIndex)) {
|
||||||
adapterToUse = adapter;
|
adapterToUse = adapter;
|
||||||
qCDebug(QRHI_LOG_INFO, " using this adapter");
|
qCDebug(QRHI_LOG_INFO, " using this adapter");
|
||||||
@ -261,9 +290,14 @@ bool QRhiD3D11::create(QRhi::Flags flags)
|
|||||||
if (FAILED(context->QueryInterface(IID_ID3DUserDefinedAnnotation, reinterpret_cast<void **>(&annotations))))
|
if (FAILED(context->QueryInterface(IID_ID3DUserDefinedAnnotation, reinterpret_cast<void **>(&annotations))))
|
||||||
annotations = nullptr;
|
annotations = nullptr;
|
||||||
|
|
||||||
|
deviceLost = false;
|
||||||
|
|
||||||
nativeHandlesStruct.dev = dev;
|
nativeHandlesStruct.dev = dev;
|
||||||
nativeHandlesStruct.context = context;
|
nativeHandlesStruct.context = context;
|
||||||
|
|
||||||
|
if (deviceCurse.framesToActivate > 0)
|
||||||
|
deviceCurse.initResources();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,6 +315,8 @@ void QRhiD3D11::destroy()
|
|||||||
|
|
||||||
clearShaderCache();
|
clearShaderCache();
|
||||||
|
|
||||||
|
deviceCurse.releaseResources();
|
||||||
|
|
||||||
if (annotations) {
|
if (annotations) {
|
||||||
annotations->Release();
|
annotations->Release();
|
||||||
annotations = nullptr;
|
annotations = nullptr;
|
||||||
@ -332,9 +368,9 @@ DXGI_SAMPLE_DESC QRhiD3D11::effectiveSampleCount(int sampleCount) const
|
|||||||
return desc;
|
return desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
desc.Count = s;
|
desc.Count = UINT(s);
|
||||||
if (s > 1)
|
if (s > 1)
|
||||||
desc.Quality = D3D11_STANDARD_MULTISAMPLE_PATTERN;
|
desc.Quality = UINT(D3D11_STANDARD_MULTISAMPLE_PATTERN);
|
||||||
else
|
else
|
||||||
desc.Quality = 0;
|
desc.Quality = 0;
|
||||||
|
|
||||||
@ -466,9 +502,10 @@ void QRhiD3D11::sendVMemStatsToProfiler()
|
|||||||
// nothing to do here
|
// nothing to do here
|
||||||
}
|
}
|
||||||
|
|
||||||
void QRhiD3D11::makeThreadLocalNativeContextCurrent()
|
bool QRhiD3D11::makeThreadLocalNativeContextCurrent()
|
||||||
{
|
{
|
||||||
// nothing to do here
|
// not applicable
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QRhiD3D11::releaseCachedResources()
|
void QRhiD3D11::releaseCachedResources()
|
||||||
@ -476,6 +513,11 @@ void QRhiD3D11::releaseCachedResources()
|
|||||||
clearShaderCache();
|
clearShaderCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QRhiD3D11::isDeviceLost() const
|
||||||
|
{
|
||||||
|
return deviceLost;
|
||||||
|
}
|
||||||
|
|
||||||
QRhiRenderBuffer *QRhiD3D11::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
|
QRhiRenderBuffer *QRhiD3D11::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
|
||||||
int sampleCount, QRhiRenderBuffer::Flags flags)
|
int sampleCount, QRhiRenderBuffer::Flags flags)
|
||||||
{
|
{
|
||||||
@ -655,7 +697,7 @@ void QRhiD3D11::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind
|
|||||||
uint *p = cmd.args.bindShaderResources.dynamicOffsetPairs;
|
uint *p = cmd.args.bindShaderResources.dynamicOffsetPairs;
|
||||||
for (int i = 0; i < dynamicOffsetCount; ++i) {
|
for (int i = 0; i < dynamicOffsetCount; ++i) {
|
||||||
const QRhiCommandBuffer::DynamicOffset &dynOfs(dynamicOffsets[i]);
|
const QRhiCommandBuffer::DynamicOffset &dynOfs(dynamicOffsets[i]);
|
||||||
const uint binding = dynOfs.first;
|
const uint binding = uint(dynOfs.first);
|
||||||
Q_ASSERT(aligned(dynOfs.second, quint32(256)) == dynOfs.second);
|
Q_ASSERT(aligned(dynOfs.second, quint32(256)) == dynOfs.second);
|
||||||
const uint offsetInConstants = dynOfs.second / 16;
|
const uint offsetInConstants = dynOfs.second / 16;
|
||||||
*p++ = binding;
|
*p++ = binding;
|
||||||
@ -791,10 +833,10 @@ void QRhiD3D11::setBlendConstants(QRhiCommandBuffer *cb, const QColor &c)
|
|||||||
QD3D11CommandBuffer::Command cmd;
|
QD3D11CommandBuffer::Command cmd;
|
||||||
cmd.cmd = QD3D11CommandBuffer::Command::BlendConstants;
|
cmd.cmd = QD3D11CommandBuffer::Command::BlendConstants;
|
||||||
cmd.args.blendConstants.ps = QRHI_RES(QD3D11GraphicsPipeline, cbD->currentGraphicsPipeline);
|
cmd.args.blendConstants.ps = QRHI_RES(QD3D11GraphicsPipeline, cbD->currentGraphicsPipeline);
|
||||||
cmd.args.blendConstants.c[0] = c.redF();
|
cmd.args.blendConstants.c[0] = float(c.redF());
|
||||||
cmd.args.blendConstants.c[1] = c.greenF();
|
cmd.args.blendConstants.c[1] = float(c.greenF());
|
||||||
cmd.args.blendConstants.c[2] = c.blueF();
|
cmd.args.blendConstants.c[2] = float(c.blueF());
|
||||||
cmd.args.blendConstants.c[3] = c.alphaF();
|
cmd.args.blendConstants.c[3] = float(c.alphaF());
|
||||||
cbD->commands.append(cmd);
|
cbD->commands.append(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -992,8 +1034,14 @@ QRhi::FrameOpResult QRhiD3D11::endFrame(QRhiSwapChain *swapChain, QRhi::EndFrame
|
|||||||
if (!flags.testFlag(QRhi::SkipPresent)) {
|
if (!flags.testFlag(QRhi::SkipPresent)) {
|
||||||
const UINT presentFlags = 0;
|
const UINT presentFlags = 0;
|
||||||
HRESULT hr = swapChainD->swapChain->Present(swapChainD->swapInterval, presentFlags);
|
HRESULT hr = swapChainD->swapChain->Present(swapChainD->swapInterval, presentFlags);
|
||||||
if (FAILED(hr))
|
if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET) {
|
||||||
|
qWarning("Device loss detected in Present()");
|
||||||
|
deviceLost = true;
|
||||||
|
return QRhi::FrameOpDeviceLost;
|
||||||
|
} else if (FAILED(hr)) {
|
||||||
qWarning("Failed to present: %s", qPrintable(comErrorMessage(hr)));
|
qWarning("Failed to present: %s", qPrintable(comErrorMessage(hr)));
|
||||||
|
return QRhi::FrameOpError;
|
||||||
|
}
|
||||||
|
|
||||||
// move on to the next buffer
|
// move on to the next buffer
|
||||||
swapChainD->currentFrameSlot = (swapChainD->currentFrameSlot + 1) % QD3D11SwapChain::BUFFER_COUNT;
|
swapChainD->currentFrameSlot = (swapChainD->currentFrameSlot + 1) % QD3D11SwapChain::BUFFER_COUNT;
|
||||||
@ -1003,6 +1051,20 @@ QRhi::FrameOpResult QRhiD3D11::endFrame(QRhiSwapChain *swapChain, QRhi::EndFrame
|
|||||||
|
|
||||||
swapChainD->frameCount += 1;
|
swapChainD->frameCount += 1;
|
||||||
contextState.currentSwapChain = nullptr;
|
contextState.currentSwapChain = nullptr;
|
||||||
|
|
||||||
|
if (deviceCurse.framesToActivate > 0) {
|
||||||
|
deviceCurse.framesLeft -= 1;
|
||||||
|
if (deviceCurse.framesLeft == 0) {
|
||||||
|
deviceCurse.framesLeft = deviceCurse.framesToActivate;
|
||||||
|
if (!deviceCurse.permanent)
|
||||||
|
deviceCurse.framesToActivate = -1;
|
||||||
|
|
||||||
|
deviceCurse.activate();
|
||||||
|
} else if (deviceCurse.framesLeft % 100 == 0) {
|
||||||
|
qDebug("Impending doom: %d frames left", deviceCurse.framesLeft);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return QRhi::FrameOpSuccess;
|
return QRhi::FrameOpSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1176,7 +1238,7 @@ QRhi::FrameOpResult QRhiD3D11::finish()
|
|||||||
void QRhiD3D11::enqueueSubresUpload(QD3D11Texture *texD, QD3D11CommandBuffer *cbD,
|
void QRhiD3D11::enqueueSubresUpload(QD3D11Texture *texD, QD3D11CommandBuffer *cbD,
|
||||||
int layer, int level, const QRhiTextureSubresourceUploadDescription &subresDesc)
|
int layer, int level, const QRhiTextureSubresourceUploadDescription &subresDesc)
|
||||||
{
|
{
|
||||||
UINT subres = D3D11CalcSubresource(level, layer, texD->mipLevelCount);
|
UINT subres = D3D11CalcSubresource(UINT(level), UINT(layer), texD->mipLevelCount);
|
||||||
const QPoint dp = subresDesc.destinationTopLeft();
|
const QPoint dp = subresDesc.destinationTopLeft();
|
||||||
D3D11_BOX box;
|
D3D11_BOX box;
|
||||||
box.front = 0;
|
box.front = 0;
|
||||||
@ -1207,13 +1269,13 @@ void QRhiD3D11::enqueueSubresUpload(QD3D11Texture *texD, QD3D11CommandBuffer *cb
|
|||||||
} else {
|
} else {
|
||||||
cmd.args.updateSubRes.src = cbD->retainImage(img);
|
cmd.args.updateSubRes.src = cbD->retainImage(img);
|
||||||
}
|
}
|
||||||
box.left = dp.x();
|
box.left = UINT(dp.x());
|
||||||
box.top = dp.y();
|
box.top = UINT(dp.y());
|
||||||
box.right = dp.x() + size.width();
|
box.right = UINT(dp.x() + size.width());
|
||||||
box.bottom = dp.y() + size.height();
|
box.bottom = UINT(dp.y() + size.height());
|
||||||
cmd.args.updateSubRes.hasDstBox = true;
|
cmd.args.updateSubRes.hasDstBox = true;
|
||||||
cmd.args.updateSubRes.dstBox = box;
|
cmd.args.updateSubRes.dstBox = box;
|
||||||
cmd.args.updateSubRes.srcRowPitch = bpl;
|
cmd.args.updateSubRes.srcRowPitch = UINT(bpl);
|
||||||
} else if (!subresDesc.data().isEmpty() && isCompressedFormat(texD->m_format)) {
|
} else if (!subresDesc.data().isEmpty() && isCompressedFormat(texD->m_format)) {
|
||||||
const QSize size = subresDesc.sourceSize().isEmpty() ? q->sizeForMipLevel(level, texD->m_pixelSize)
|
const QSize size = subresDesc.sourceSize().isEmpty() ? q->sizeForMipLevel(level, texD->m_pixelSize)
|
||||||
: subresDesc.sourceSize();
|
: subresDesc.sourceSize();
|
||||||
@ -1223,10 +1285,10 @@ void QRhiD3D11::enqueueSubresUpload(QD3D11Texture *texD, QD3D11CommandBuffer *cb
|
|||||||
// Everything must be a multiple of the block width and
|
// Everything must be a multiple of the block width and
|
||||||
// height, so e.g. a mip level of size 2x2 will be 4x4 when it
|
// height, so e.g. a mip level of size 2x2 will be 4x4 when it
|
||||||
// comes to the actual data.
|
// comes to the actual data.
|
||||||
box.left = aligned(dp.x(), blockDim.width());
|
box.left = UINT(aligned(dp.x(), blockDim.width()));
|
||||||
box.top = aligned(dp.y(), blockDim.height());
|
box.top = UINT(aligned(dp.y(), blockDim.height()));
|
||||||
box.right = aligned(dp.x() + size.width(), blockDim.width());
|
box.right = UINT(aligned(dp.x() + size.width(), blockDim.width()));
|
||||||
box.bottom = aligned(dp.y() + size.height(), blockDim.height());
|
box.bottom = UINT(aligned(dp.y() + size.height(), blockDim.height()));
|
||||||
cmd.args.updateSubRes.hasDstBox = true;
|
cmd.args.updateSubRes.hasDstBox = true;
|
||||||
cmd.args.updateSubRes.dstBox = box;
|
cmd.args.updateSubRes.dstBox = box;
|
||||||
cmd.args.updateSubRes.src = cbD->retainData(subresDesc.data());
|
cmd.args.updateSubRes.src = cbD->retainData(subresDesc.data());
|
||||||
@ -1236,10 +1298,10 @@ void QRhiD3D11::enqueueSubresUpload(QD3D11Texture *texD, QD3D11CommandBuffer *cb
|
|||||||
: subresDesc.sourceSize();
|
: subresDesc.sourceSize();
|
||||||
quint32 bpl = 0;
|
quint32 bpl = 0;
|
||||||
textureFormatInfo(texD->m_format, size, &bpl, nullptr);
|
textureFormatInfo(texD->m_format, size, &bpl, nullptr);
|
||||||
box.left = dp.x();
|
box.left = UINT(dp.x());
|
||||||
box.top = dp.y();
|
box.top = UINT(dp.y());
|
||||||
box.right = dp.x() + size.width();
|
box.right = UINT(dp.x() + size.width());
|
||||||
box.bottom = dp.y() + size.height();
|
box.bottom = UINT(dp.y() + size.height());
|
||||||
cmd.args.updateSubRes.hasDstBox = true;
|
cmd.args.updateSubRes.hasDstBox = true;
|
||||||
cmd.args.updateSubRes.dstBox = box;
|
cmd.args.updateSubRes.dstBox = box;
|
||||||
cmd.args.updateSubRes.src = cbD->retainData(subresDesc.data());
|
cmd.args.updateSubRes.src = cbD->retainData(subresDesc.data());
|
||||||
@ -1261,7 +1323,7 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
|
|||||||
for (const QRhiResourceUpdateBatchPrivate::DynamicBufferUpdate &u : ud->dynamicBufferUpdates) {
|
for (const QRhiResourceUpdateBatchPrivate::DynamicBufferUpdate &u : ud->dynamicBufferUpdates) {
|
||||||
QD3D11Buffer *bufD = QRHI_RES(QD3D11Buffer, u.buf);
|
QD3D11Buffer *bufD = QRHI_RES(QD3D11Buffer, u.buf);
|
||||||
Q_ASSERT(bufD->m_type == QRhiBuffer::Dynamic);
|
Q_ASSERT(bufD->m_type == QRhiBuffer::Dynamic);
|
||||||
memcpy(bufD->dynBuf.data() + u.offset, u.data.constData(), u.data.size());
|
memcpy(bufD->dynBuf.data() + u.offset, u.data.constData(), size_t(u.data.size()));
|
||||||
bufD->hasPendingDynamicUpdates = true;
|
bufD->hasPendingDynamicUpdates = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1279,10 +1341,10 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
|
|||||||
// since the ID3D11Buffer's size is rounded up to be a multiple of 256
|
// since the ID3D11Buffer's size is rounded up to be a multiple of 256
|
||||||
// while the data we have has the original size.
|
// while the data we have has the original size.
|
||||||
D3D11_BOX box;
|
D3D11_BOX box;
|
||||||
box.left = u.offset;
|
box.left = UINT(u.offset);
|
||||||
box.top = box.front = 0;
|
box.top = box.front = 0;
|
||||||
box.back = box.bottom = 1;
|
box.back = box.bottom = 1;
|
||||||
box.right = u.offset + u.data.size(); // no -1: right, bottom, back are exclusive, see D3D11_BOX doc
|
box.right = UINT(u.offset + u.data.size()); // no -1: right, bottom, back are exclusive, see D3D11_BOX doc
|
||||||
cmd.args.updateSubRes.hasDstBox = true;
|
cmd.args.updateSubRes.hasDstBox = true;
|
||||||
cmd.args.updateSubRes.dstBox = box;
|
cmd.args.updateSubRes.dstBox = box;
|
||||||
cbD->commands.append(cmd);
|
cbD->commands.append(cmd);
|
||||||
@ -1301,25 +1363,25 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
|
|||||||
Q_ASSERT(u.copy.src && u.copy.dst);
|
Q_ASSERT(u.copy.src && u.copy.dst);
|
||||||
QD3D11Texture *srcD = QRHI_RES(QD3D11Texture, u.copy.src);
|
QD3D11Texture *srcD = QRHI_RES(QD3D11Texture, u.copy.src);
|
||||||
QD3D11Texture *dstD = QRHI_RES(QD3D11Texture, u.copy.dst);
|
QD3D11Texture *dstD = QRHI_RES(QD3D11Texture, u.copy.dst);
|
||||||
UINT srcSubRes = D3D11CalcSubresource(u.copy.desc.sourceLevel(), u.copy.desc.sourceLayer(), srcD->mipLevelCount);
|
UINT srcSubRes = D3D11CalcSubresource(UINT(u.copy.desc.sourceLevel()), UINT(u.copy.desc.sourceLayer()), srcD->mipLevelCount);
|
||||||
UINT dstSubRes = D3D11CalcSubresource(u.copy.desc.destinationLevel(), u.copy.desc.destinationLayer(), dstD->mipLevelCount);
|
UINT dstSubRes = D3D11CalcSubresource(UINT(u.copy.desc.destinationLevel()), UINT(u.copy.desc.destinationLayer()), dstD->mipLevelCount);
|
||||||
const QPoint dp = u.copy.desc.destinationTopLeft();
|
const QPoint dp = u.copy.desc.destinationTopLeft();
|
||||||
const QSize size = u.copy.desc.pixelSize().isEmpty() ? srcD->m_pixelSize : u.copy.desc.pixelSize();
|
const QSize size = u.copy.desc.pixelSize().isEmpty() ? srcD->m_pixelSize : u.copy.desc.pixelSize();
|
||||||
const QPoint sp = u.copy.desc.sourceTopLeft();
|
const QPoint sp = u.copy.desc.sourceTopLeft();
|
||||||
D3D11_BOX srcBox;
|
D3D11_BOX srcBox;
|
||||||
srcBox.left = sp.x();
|
srcBox.left = UINT(sp.x());
|
||||||
srcBox.top = sp.y();
|
srcBox.top = UINT(sp.y());
|
||||||
srcBox.front = 0;
|
srcBox.front = 0;
|
||||||
// back, right, bottom are exclusive
|
// back, right, bottom are exclusive
|
||||||
srcBox.right = srcBox.left + size.width();
|
srcBox.right = srcBox.left + UINT(size.width());
|
||||||
srcBox.bottom = srcBox.top + size.height();
|
srcBox.bottom = srcBox.top + UINT(size.height());
|
||||||
srcBox.back = 1;
|
srcBox.back = 1;
|
||||||
QD3D11CommandBuffer::Command cmd;
|
QD3D11CommandBuffer::Command cmd;
|
||||||
cmd.cmd = QD3D11CommandBuffer::Command::CopySubRes;
|
cmd.cmd = QD3D11CommandBuffer::Command::CopySubRes;
|
||||||
cmd.args.copySubRes.dst = dstD->tex;
|
cmd.args.copySubRes.dst = dstD->tex;
|
||||||
cmd.args.copySubRes.dstSubRes = dstSubRes;
|
cmd.args.copySubRes.dstSubRes = dstSubRes;
|
||||||
cmd.args.copySubRes.dstX = dp.x();
|
cmd.args.copySubRes.dstX = UINT(dp.x());
|
||||||
cmd.args.copySubRes.dstY = dp.y();
|
cmd.args.copySubRes.dstY = UINT(dp.y());
|
||||||
cmd.args.copySubRes.src = srcD->tex;
|
cmd.args.copySubRes.src = srcD->tex;
|
||||||
cmd.args.copySubRes.srcSubRes = srcSubRes;
|
cmd.args.copySubRes.srcSubRes = srcSubRes;
|
||||||
cmd.args.copySubRes.hasSrcBox = true;
|
cmd.args.copySubRes.hasSrcBox = true;
|
||||||
@ -1347,7 +1409,7 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
|
|||||||
dxgiFormat = texD->dxgiFormat;
|
dxgiFormat = texD->dxgiFormat;
|
||||||
pixelSize = u.read.rb.level() > 0 ? q->sizeForMipLevel(u.read.rb.level(), texD->m_pixelSize) : texD->m_pixelSize;
|
pixelSize = u.read.rb.level() > 0 ? q->sizeForMipLevel(u.read.rb.level(), texD->m_pixelSize) : texD->m_pixelSize;
|
||||||
format = texD->m_format;
|
format = texD->m_format;
|
||||||
subres = D3D11CalcSubresource(u.read.rb.level(), u.read.rb.layer(), texD->mipLevelCount);
|
subres = D3D11CalcSubresource(UINT(u.read.rb.level()), UINT(u.read.rb.layer()), texD->mipLevelCount);
|
||||||
} else {
|
} else {
|
||||||
Q_ASSERT(contextState.currentSwapChain);
|
Q_ASSERT(contextState.currentSwapChain);
|
||||||
swapChainD = QRHI_RES(QD3D11SwapChain, contextState.currentSwapChain);
|
swapChainD = QRHI_RES(QD3D11SwapChain, contextState.currentSwapChain);
|
||||||
@ -1376,8 +1438,8 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
|
|||||||
|
|
||||||
D3D11_TEXTURE2D_DESC desc;
|
D3D11_TEXTURE2D_DESC desc;
|
||||||
memset(&desc, 0, sizeof(desc));
|
memset(&desc, 0, sizeof(desc));
|
||||||
desc.Width = pixelSize.width();
|
desc.Width = UINT(pixelSize.width());
|
||||||
desc.Height = pixelSize.height();
|
desc.Height = UINT(pixelSize.height());
|
||||||
desc.MipLevels = 1;
|
desc.MipLevels = 1;
|
||||||
desc.ArraySize = 1;
|
desc.ArraySize = 1;
|
||||||
desc.Format = dxgiFormat;
|
desc.Format = dxgiFormat;
|
||||||
@ -1390,7 +1452,7 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
|
|||||||
qWarning("Failed to create readback staging texture: %s", qPrintable(comErrorMessage(hr)));
|
qWarning("Failed to create readback staging texture: %s", qPrintable(comErrorMessage(hr)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QRHI_PROF_F(newReadbackBuffer(quint64(quintptr(stagingTex)),
|
QRHI_PROF_F(newReadbackBuffer(qint64(qintptr(stagingTex)),
|
||||||
texD ? static_cast<QRhiResource *>(texD) : static_cast<QRhiResource *>(swapChainD),
|
texD ? static_cast<QRhiResource *>(texD) : static_cast<QRhiResource *>(swapChainD),
|
||||||
bufSize));
|
bufSize));
|
||||||
|
|
||||||
@ -1433,7 +1495,7 @@ void QRhiD3D11::finishActiveReadbacks()
|
|||||||
const QRhiD3D11::ActiveReadback &aRb(activeReadbacks[i]);
|
const QRhiD3D11::ActiveReadback &aRb(activeReadbacks[i]);
|
||||||
aRb.result->format = aRb.format;
|
aRb.result->format = aRb.format;
|
||||||
aRb.result->pixelSize = aRb.pixelSize;
|
aRb.result->pixelSize = aRb.pixelSize;
|
||||||
aRb.result->data.resize(aRb.bufSize);
|
aRb.result->data.resize(int(aRb.bufSize));
|
||||||
|
|
||||||
D3D11_MAPPED_SUBRESOURCE mp;
|
D3D11_MAPPED_SUBRESOURCE mp;
|
||||||
HRESULT hr = context->Map(aRb.stagingTex, 0, D3D11_MAP_READ, 0, &mp);
|
HRESULT hr = context->Map(aRb.stagingTex, 0, D3D11_MAP_READ, 0, &mp);
|
||||||
@ -1454,7 +1516,7 @@ void QRhiD3D11::finishActiveReadbacks()
|
|||||||
context->Unmap(aRb.stagingTex, 0);
|
context->Unmap(aRb.stagingTex, 0);
|
||||||
|
|
||||||
aRb.stagingTex->Release();
|
aRb.stagingTex->Release();
|
||||||
QRHI_PROF_F(releaseReadbackBuffer(quint64(quintptr(aRb.stagingTex))));
|
QRHI_PROF_F(releaseReadbackBuffer(qint64(qintptr(aRb.stagingTex))));
|
||||||
|
|
||||||
if (aRb.result->completed)
|
if (aRb.result->completed)
|
||||||
completedCallbacks.append(aRb.result->completed);
|
completedCallbacks.append(aRb.result->completed);
|
||||||
@ -1523,10 +1585,10 @@ void QRhiD3D11::beginPass(QRhiCommandBuffer *cb,
|
|||||||
if (rtD->dsAttCount && wantsDsClear)
|
if (rtD->dsAttCount && wantsDsClear)
|
||||||
clearCmd.args.clear.mask |= QD3D11CommandBuffer::Command::Depth | QD3D11CommandBuffer::Command::Stencil;
|
clearCmd.args.clear.mask |= QD3D11CommandBuffer::Command::Depth | QD3D11CommandBuffer::Command::Stencil;
|
||||||
|
|
||||||
clearCmd.args.clear.c[0] = colorClearValue.redF();
|
clearCmd.args.clear.c[0] = float(colorClearValue.redF());
|
||||||
clearCmd.args.clear.c[1] = colorClearValue.greenF();
|
clearCmd.args.clear.c[1] = float(colorClearValue.greenF());
|
||||||
clearCmd.args.clear.c[2] = colorClearValue.blueF();
|
clearCmd.args.clear.c[2] = float(colorClearValue.blueF());
|
||||||
clearCmd.args.clear.c[3] = colorClearValue.alphaF();
|
clearCmd.args.clear.c[3] = float(colorClearValue.alphaF());
|
||||||
clearCmd.args.clear.d = depthStencilClearValue.depthClearValue();
|
clearCmd.args.clear.d = depthStencilClearValue.depthClearValue();
|
||||||
clearCmd.args.clear.s = depthStencilClearValue.stencilClearValue();
|
clearCmd.args.clear.s = depthStencilClearValue.stencilClearValue();
|
||||||
cbD->commands.append(clearCmd);
|
cbD->commands.append(clearCmd);
|
||||||
@ -1557,8 +1619,8 @@ void QRhiD3D11::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resource
|
|||||||
QD3D11CommandBuffer::Command cmd;
|
QD3D11CommandBuffer::Command cmd;
|
||||||
cmd.cmd = QD3D11CommandBuffer::Command::ResolveSubRes;
|
cmd.cmd = QD3D11CommandBuffer::Command::ResolveSubRes;
|
||||||
cmd.args.resolveSubRes.dst = dstTexD->tex;
|
cmd.args.resolveSubRes.dst = dstTexD->tex;
|
||||||
cmd.args.resolveSubRes.dstSubRes = D3D11CalcSubresource(colorAtt.resolveLevel(),
|
cmd.args.resolveSubRes.dstSubRes = D3D11CalcSubresource(UINT(colorAtt.resolveLevel()),
|
||||||
colorAtt.resolveLayer(),
|
UINT(colorAtt.resolveLayer()),
|
||||||
dstTexD->mipLevelCount);
|
dstTexD->mipLevelCount);
|
||||||
if (srcTexD) {
|
if (srcTexD) {
|
||||||
cmd.args.resolveSubRes.src = srcTexD->tex;
|
cmd.args.resolveSubRes.src = srcTexD->tex;
|
||||||
@ -1585,7 +1647,7 @@ void QRhiD3D11::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resource
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cmd.args.resolveSubRes.srcSubRes = D3D11CalcSubresource(0, colorAtt.layer(), 1);
|
cmd.args.resolveSubRes.srcSubRes = D3D11CalcSubresource(0, UINT(colorAtt.layer()), 1);
|
||||||
cmd.args.resolveSubRes.format = dstTexD->dxgiFormat;
|
cmd.args.resolveSubRes.format = dstTexD->dxgiFormat;
|
||||||
cbD->commands.append(cmd);
|
cbD->commands.append(cmd);
|
||||||
}
|
}
|
||||||
@ -1652,9 +1714,9 @@ void QRhiD3D11::dispatch(QRhiCommandBuffer *cb, int x, int y, int z)
|
|||||||
|
|
||||||
QD3D11CommandBuffer::Command cmd;
|
QD3D11CommandBuffer::Command cmd;
|
||||||
cmd.cmd = QD3D11CommandBuffer::Command::Dispatch;
|
cmd.cmd = QD3D11CommandBuffer::Command::Dispatch;
|
||||||
cmd.args.dispatch.x = x;
|
cmd.args.dispatch.x = UINT(x);
|
||||||
cmd.args.dispatch.y = y;
|
cmd.args.dispatch.y = UINT(y);
|
||||||
cmd.args.dispatch.z = z;
|
cmd.args.dispatch.z = UINT(z);
|
||||||
cbD->commands.append(cmd);
|
cbD->commands.append(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1696,11 +1758,11 @@ void QRhiD3D11::updateShaderResourceBindings(QD3D11ShaderResourceBindings *srbD)
|
|||||||
// dynamic ubuf offsets are not considered here, those are baked in
|
// dynamic ubuf offsets are not considered here, those are baked in
|
||||||
// at a later stage, which is good as vsubufoffsets and friends are
|
// at a later stage, which is good as vsubufoffsets and friends are
|
||||||
// per-srb, not per-setShaderResources call
|
// per-srb, not per-setShaderResources call
|
||||||
const uint offsetInConstants = b->u.ubuf.offset / 16;
|
const uint offsetInConstants = uint(b->u.ubuf.offset) / 16;
|
||||||
// size must be 16 mult. (in constants, i.e. multiple of 256 bytes).
|
// size must be 16 mult. (in constants, i.e. multiple of 256 bytes).
|
||||||
// We can round up if needed since the buffers's actual size
|
// We can round up if needed since the buffers's actual size
|
||||||
// (ByteWidth) is always a multiple of 256.
|
// (ByteWidth) is always a multiple of 256.
|
||||||
const uint sizeInConstants = aligned(b->u.ubuf.maybeSize ? b->u.ubuf.maybeSize : bufD->m_size, 256) / 16;
|
const uint sizeInConstants = uint(aligned(b->u.ubuf.maybeSize ? b->u.ubuf.maybeSize : bufD->m_size, 256) / 16);
|
||||||
if (b->stage.testFlag(QRhiShaderResourceBinding::VertexStage)) {
|
if (b->stage.testFlag(QRhiShaderResourceBinding::VertexStage)) {
|
||||||
srbD->vsubufs.feed(b->binding, bufD->buffer);
|
srbD->vsubufs.feed(b->binding, bufD->buffer);
|
||||||
srbD->vsubufoffsets.feed(b->binding, offsetInConstants);
|
srbD->vsubufoffsets.feed(b->binding, offsetInConstants);
|
||||||
@ -1818,7 +1880,7 @@ void QRhiD3D11::executeBufferHostWritesForCurrentFrame(QD3D11Buffer *bufD)
|
|||||||
D3D11_MAPPED_SUBRESOURCE mp;
|
D3D11_MAPPED_SUBRESOURCE mp;
|
||||||
HRESULT hr = context->Map(bufD->buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mp);
|
HRESULT hr = context->Map(bufD->buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mp);
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
memcpy(mp.pData, bufD->dynBuf.constData(), bufD->dynBuf.size());
|
memcpy(mp.pData, bufD->dynBuf.constData(), size_t(bufD->dynBuf.size()));
|
||||||
context->Unmap(bufD->buffer, 0);
|
context->Unmap(bufD->buffer, 0);
|
||||||
} else {
|
} else {
|
||||||
qWarning("Failed to map buffer: %s", qPrintable(comErrorMessage(hr)));
|
qWarning("Failed to map buffer: %s", qPrintable(comErrorMessage(hr)));
|
||||||
@ -1831,13 +1893,13 @@ static void applyDynamicOffsets(QVarLengthArray<UINT, 4> *offsets,
|
|||||||
QRhiBatchedBindings<UINT> *ubufoffsets,
|
QRhiBatchedBindings<UINT> *ubufoffsets,
|
||||||
const uint *dynOfsPairs, int dynOfsPairCount)
|
const uint *dynOfsPairs, int dynOfsPairCount)
|
||||||
{
|
{
|
||||||
const UINT count = ubufs->batches[batchIndex].resources.count();
|
const int count = ubufs->batches[batchIndex].resources.count();
|
||||||
const UINT startBinding = ubufs->batches[batchIndex].startBinding;
|
const UINT startBinding = ubufs->batches[batchIndex].startBinding;
|
||||||
*offsets = ubufoffsets->batches[batchIndex].resources;
|
*offsets = ubufoffsets->batches[batchIndex].resources;
|
||||||
for (UINT b = 0; b < count; ++b) {
|
for (int b = 0; b < count; ++b) {
|
||||||
for (int di = 0; di < dynOfsPairCount; ++di) {
|
for (int di = 0; di < dynOfsPairCount; ++di) {
|
||||||
const uint binding = dynOfsPairs[2 * di];
|
const uint binding = dynOfsPairs[2 * di];
|
||||||
if (binding == startBinding + b) {
|
if (binding == startBinding + UINT(b)) {
|
||||||
const uint offsetInConstants = dynOfsPairs[2 * di + 1];
|
const uint offsetInConstants = dynOfsPairs[2 * di + 1];
|
||||||
(*offsets)[b] = offsetInConstants;
|
(*offsets)[b] = offsetInConstants;
|
||||||
break;
|
break;
|
||||||
@ -1852,37 +1914,37 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
|
|||||||
{
|
{
|
||||||
if (!offsetOnlyChange) {
|
if (!offsetOnlyChange) {
|
||||||
for (const auto &batch : srbD->vssamplers.batches)
|
for (const auto &batch : srbD->vssamplers.batches)
|
||||||
context->VSSetSamplers(batch.startBinding, batch.resources.count(), batch.resources.constData());
|
context->VSSetSamplers(batch.startBinding, UINT(batch.resources.count()), batch.resources.constData());
|
||||||
|
|
||||||
for (const auto &batch : srbD->vsshaderresources.batches) {
|
for (const auto &batch : srbD->vsshaderresources.batches) {
|
||||||
context->VSSetShaderResources(batch.startBinding, batch.resources.count(), batch.resources.constData());
|
context->VSSetShaderResources(batch.startBinding, UINT(batch.resources.count()), batch.resources.constData());
|
||||||
contextState.vsHighestActiveSrvBinding = qMax<int>(contextState.vsHighestActiveSrvBinding,
|
contextState.vsHighestActiveSrvBinding = qMax<int>(contextState.vsHighestActiveSrvBinding,
|
||||||
batch.startBinding + batch.resources.count() - 1);
|
int(batch.startBinding) + batch.resources.count() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &batch : srbD->fssamplers.batches)
|
for (const auto &batch : srbD->fssamplers.batches)
|
||||||
context->PSSetSamplers(batch.startBinding, batch.resources.count(), batch.resources.constData());
|
context->PSSetSamplers(batch.startBinding, UINT(batch.resources.count()), batch.resources.constData());
|
||||||
|
|
||||||
for (const auto &batch : srbD->fsshaderresources.batches) {
|
for (const auto &batch : srbD->fsshaderresources.batches) {
|
||||||
context->PSSetShaderResources(batch.startBinding, batch.resources.count(), batch.resources.constData());
|
context->PSSetShaderResources(batch.startBinding, UINT(batch.resources.count()), batch.resources.constData());
|
||||||
contextState.fsHighestActiveSrvBinding = qMax<int>(contextState.fsHighestActiveSrvBinding,
|
contextState.fsHighestActiveSrvBinding = qMax<int>(contextState.fsHighestActiveSrvBinding,
|
||||||
batch.startBinding + batch.resources.count() - 1);
|
int(batch.startBinding) + batch.resources.count() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &batch : srbD->cssamplers.batches)
|
for (const auto &batch : srbD->cssamplers.batches)
|
||||||
context->CSSetSamplers(batch.startBinding, batch.resources.count(), batch.resources.constData());
|
context->CSSetSamplers(batch.startBinding, UINT(batch.resources.count()), batch.resources.constData());
|
||||||
|
|
||||||
for (const auto &batch : srbD->csshaderresources.batches) {
|
for (const auto &batch : srbD->csshaderresources.batches) {
|
||||||
context->CSSetShaderResources(batch.startBinding, batch.resources.count(), batch.resources.constData());
|
context->CSSetShaderResources(batch.startBinding, UINT(batch.resources.count()), batch.resources.constData());
|
||||||
contextState.csHighestActiveSrvBinding = qMax<int>(contextState.csHighestActiveSrvBinding,
|
contextState.csHighestActiveSrvBinding = qMax<int>(contextState.csHighestActiveSrvBinding,
|
||||||
batch.startBinding + batch.resources.count() - 1);
|
int(batch.startBinding) + batch.resources.count() - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0, ie = srbD->vsubufs.batches.count(); i != ie; ++i) {
|
for (int i = 0, ie = srbD->vsubufs.batches.count(); i != ie; ++i) {
|
||||||
if (!dynOfsPairCount) {
|
if (!dynOfsPairCount) {
|
||||||
context->VSSetConstantBuffers1(srbD->vsubufs.batches[i].startBinding,
|
context->VSSetConstantBuffers1(srbD->vsubufs.batches[i].startBinding,
|
||||||
srbD->vsubufs.batches[i].resources.count(),
|
UINT(srbD->vsubufs.batches[i].resources.count()),
|
||||||
srbD->vsubufs.batches[i].resources.constData(),
|
srbD->vsubufs.batches[i].resources.constData(),
|
||||||
srbD->vsubufoffsets.batches[i].resources.constData(),
|
srbD->vsubufoffsets.batches[i].resources.constData(),
|
||||||
srbD->vsubufsizes.batches[i].resources.constData());
|
srbD->vsubufsizes.batches[i].resources.constData());
|
||||||
@ -1890,7 +1952,7 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
|
|||||||
QVarLengthArray<UINT, 4> offsets;
|
QVarLengthArray<UINT, 4> offsets;
|
||||||
applyDynamicOffsets(&offsets, i, &srbD->vsubufs, &srbD->vsubufoffsets, dynOfsPairs, dynOfsPairCount);
|
applyDynamicOffsets(&offsets, i, &srbD->vsubufs, &srbD->vsubufoffsets, dynOfsPairs, dynOfsPairCount);
|
||||||
context->VSSetConstantBuffers1(srbD->vsubufs.batches[i].startBinding,
|
context->VSSetConstantBuffers1(srbD->vsubufs.batches[i].startBinding,
|
||||||
srbD->vsubufs.batches[i].resources.count(),
|
UINT(srbD->vsubufs.batches[i].resources.count()),
|
||||||
srbD->vsubufs.batches[i].resources.constData(),
|
srbD->vsubufs.batches[i].resources.constData(),
|
||||||
offsets.constData(),
|
offsets.constData(),
|
||||||
srbD->vsubufsizes.batches[i].resources.constData());
|
srbD->vsubufsizes.batches[i].resources.constData());
|
||||||
@ -1900,7 +1962,7 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
|
|||||||
for (int i = 0, ie = srbD->fsubufs.batches.count(); i != ie; ++i) {
|
for (int i = 0, ie = srbD->fsubufs.batches.count(); i != ie; ++i) {
|
||||||
if (!dynOfsPairCount) {
|
if (!dynOfsPairCount) {
|
||||||
context->PSSetConstantBuffers1(srbD->fsubufs.batches[i].startBinding,
|
context->PSSetConstantBuffers1(srbD->fsubufs.batches[i].startBinding,
|
||||||
srbD->fsubufs.batches[i].resources.count(),
|
UINT(srbD->fsubufs.batches[i].resources.count()),
|
||||||
srbD->fsubufs.batches[i].resources.constData(),
|
srbD->fsubufs.batches[i].resources.constData(),
|
||||||
srbD->fsubufoffsets.batches[i].resources.constData(),
|
srbD->fsubufoffsets.batches[i].resources.constData(),
|
||||||
srbD->fsubufsizes.batches[i].resources.constData());
|
srbD->fsubufsizes.batches[i].resources.constData());
|
||||||
@ -1908,7 +1970,7 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
|
|||||||
QVarLengthArray<UINT, 4> offsets;
|
QVarLengthArray<UINT, 4> offsets;
|
||||||
applyDynamicOffsets(&offsets, i, &srbD->fsubufs, &srbD->fsubufoffsets, dynOfsPairs, dynOfsPairCount);
|
applyDynamicOffsets(&offsets, i, &srbD->fsubufs, &srbD->fsubufoffsets, dynOfsPairs, dynOfsPairCount);
|
||||||
context->PSSetConstantBuffers1(srbD->fsubufs.batches[i].startBinding,
|
context->PSSetConstantBuffers1(srbD->fsubufs.batches[i].startBinding,
|
||||||
srbD->fsubufs.batches[i].resources.count(),
|
UINT(srbD->fsubufs.batches[i].resources.count()),
|
||||||
srbD->fsubufs.batches[i].resources.constData(),
|
srbD->fsubufs.batches[i].resources.constData(),
|
||||||
offsets.constData(),
|
offsets.constData(),
|
||||||
srbD->fsubufsizes.batches[i].resources.constData());
|
srbD->fsubufsizes.batches[i].resources.constData());
|
||||||
@ -1918,7 +1980,7 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
|
|||||||
for (int i = 0, ie = srbD->csubufs.batches.count(); i != ie; ++i) {
|
for (int i = 0, ie = srbD->csubufs.batches.count(); i != ie; ++i) {
|
||||||
if (!dynOfsPairCount) {
|
if (!dynOfsPairCount) {
|
||||||
context->CSSetConstantBuffers1(srbD->csubufs.batches[i].startBinding,
|
context->CSSetConstantBuffers1(srbD->csubufs.batches[i].startBinding,
|
||||||
srbD->csubufs.batches[i].resources.count(),
|
UINT(srbD->csubufs.batches[i].resources.count()),
|
||||||
srbD->csubufs.batches[i].resources.constData(),
|
srbD->csubufs.batches[i].resources.constData(),
|
||||||
srbD->csubufoffsets.batches[i].resources.constData(),
|
srbD->csubufoffsets.batches[i].resources.constData(),
|
||||||
srbD->csubufsizes.batches[i].resources.constData());
|
srbD->csubufsizes.batches[i].resources.constData());
|
||||||
@ -1926,7 +1988,7 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
|
|||||||
QVarLengthArray<UINT, 4> offsets;
|
QVarLengthArray<UINT, 4> offsets;
|
||||||
applyDynamicOffsets(&offsets, i, &srbD->csubufs, &srbD->csubufoffsets, dynOfsPairs, dynOfsPairCount);
|
applyDynamicOffsets(&offsets, i, &srbD->csubufs, &srbD->csubufoffsets, dynOfsPairs, dynOfsPairCount);
|
||||||
context->CSSetConstantBuffers1(srbD->csubufs.batches[i].startBinding,
|
context->CSSetConstantBuffers1(srbD->csubufs.batches[i].startBinding,
|
||||||
srbD->csubufs.batches[i].resources.count(),
|
UINT(srbD->csubufs.batches[i].resources.count()),
|
||||||
srbD->csubufs.batches[i].resources.constData(),
|
srbD->csubufs.batches[i].resources.constData(),
|
||||||
offsets.constData(),
|
offsets.constData(),
|
||||||
srbD->csubufsizes.batches[i].resources.constData());
|
srbD->csubufsizes.batches[i].resources.constData());
|
||||||
@ -1935,13 +1997,13 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
|
|||||||
|
|
||||||
for (int i = 0, ie = srbD->csUAVs.batches.count(); i != ie; ++i) {
|
for (int i = 0, ie = srbD->csUAVs.batches.count(); i != ie; ++i) {
|
||||||
const uint startBinding = srbD->csUAVs.batches[i].startBinding;
|
const uint startBinding = srbD->csUAVs.batches[i].startBinding;
|
||||||
const uint count = srbD->csUAVs.batches[i].resources.count();
|
const uint count = uint(srbD->csUAVs.batches[i].resources.count());
|
||||||
context->CSSetUnorderedAccessViews(startBinding,
|
context->CSSetUnorderedAccessViews(startBinding,
|
||||||
count,
|
count,
|
||||||
srbD->csUAVs.batches[i].resources.constData(),
|
srbD->csUAVs.batches[i].resources.constData(),
|
||||||
nullptr);
|
nullptr);
|
||||||
contextState.csHighestActiveUavBinding = qMax<int>(contextState.csHighestActiveUavBinding,
|
contextState.csHighestActiveUavBinding = qMax<int>(contextState.csHighestActiveUavBinding,
|
||||||
startBinding + count - 1);
|
int(startBinding + count - 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1965,7 +2027,7 @@ void QRhiD3D11::resetShaderResources()
|
|||||||
QVarLengthArray<UINT, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT> nulloffsets(count);
|
QVarLengthArray<UINT, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT> nulloffsets(count);
|
||||||
for (int i = 0; i < count; ++i)
|
for (int i = 0; i < count; ++i)
|
||||||
nulloffsets[i] = 0;
|
nulloffsets[i] = 0;
|
||||||
context->IASetVertexBuffers(0, count, nullbufs.constData(), nullstrides.constData(), nulloffsets.constData());
|
context->IASetVertexBuffers(0, UINT(count), nullbufs.constData(), nullstrides.constData(), nulloffsets.constData());
|
||||||
contextState.vsHighestActiveVertexBufferBinding = -1;
|
contextState.vsHighestActiveVertexBufferBinding = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1978,15 +2040,15 @@ void QRhiD3D11::resetShaderResources()
|
|||||||
for (int i = 0; i < nullsrvs.count(); ++i)
|
for (int i = 0; i < nullsrvs.count(); ++i)
|
||||||
nullsrvs[i] = nullptr;
|
nullsrvs[i] = nullptr;
|
||||||
if (contextState.vsHighestActiveSrvBinding >= 0) {
|
if (contextState.vsHighestActiveSrvBinding >= 0) {
|
||||||
context->VSSetShaderResources(0, contextState.vsHighestActiveSrvBinding + 1, nullsrvs.constData());
|
context->VSSetShaderResources(0, UINT(contextState.vsHighestActiveSrvBinding + 1), nullsrvs.constData());
|
||||||
contextState.vsHighestActiveSrvBinding = -1;
|
contextState.vsHighestActiveSrvBinding = -1;
|
||||||
}
|
}
|
||||||
if (contextState.fsHighestActiveSrvBinding >= 0) {
|
if (contextState.fsHighestActiveSrvBinding >= 0) {
|
||||||
context->PSSetShaderResources(0, contextState.fsHighestActiveSrvBinding + 1, nullsrvs.constData());
|
context->PSSetShaderResources(0, UINT(contextState.fsHighestActiveSrvBinding + 1), nullsrvs.constData());
|
||||||
contextState.fsHighestActiveSrvBinding = -1;
|
contextState.fsHighestActiveSrvBinding = -1;
|
||||||
}
|
}
|
||||||
if (contextState.csHighestActiveSrvBinding >= 0) {
|
if (contextState.csHighestActiveSrvBinding >= 0) {
|
||||||
context->CSSetShaderResources(0, contextState.csHighestActiveSrvBinding + 1, nullsrvs.constData());
|
context->CSSetShaderResources(0, UINT(contextState.csHighestActiveSrvBinding + 1), nullsrvs.constData());
|
||||||
contextState.csHighestActiveSrvBinding = -1;
|
contextState.csHighestActiveSrvBinding = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1997,7 +2059,7 @@ void QRhiD3D11::resetShaderResources()
|
|||||||
D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT> nulluavs(nulluavCount);
|
D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT> nulluavs(nulluavCount);
|
||||||
for (int i = 0; i < nulluavCount; ++i)
|
for (int i = 0; i < nulluavCount; ++i)
|
||||||
nulluavs[i] = nullptr;
|
nulluavs[i] = nullptr;
|
||||||
context->CSSetUnorderedAccessViews(0, nulluavCount, nulluavs.constData(), nullptr);
|
context->CSSetUnorderedAccessViews(0, UINT(nulluavCount), nulluavs.constData(), nullptr);
|
||||||
contextState.csHighestActiveUavBinding = -1;
|
contextState.csHighestActiveUavBinding = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2019,7 +2081,7 @@ void QRhiD3D11::executeCommandBuffer(QD3D11CommandBuffer *cbD, QD3D11SwapChain *
|
|||||||
// writing the first timestamp only afterwards.
|
// writing the first timestamp only afterwards.
|
||||||
context->Begin(tsDisjoint);
|
context->Begin(tsDisjoint);
|
||||||
QD3D11RenderTargetData *rtD = rtData(×tampSwapChain->rt);
|
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
|
context->End(tsStart); // just record a timestamp, no Begin needed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2032,7 +2094,7 @@ void QRhiD3D11::executeCommandBuffer(QD3D11CommandBuffer *cbD, QD3D11SwapChain *
|
|||||||
case QD3D11CommandBuffer::Command::SetRenderTarget:
|
case QD3D11CommandBuffer::Command::SetRenderTarget:
|
||||||
{
|
{
|
||||||
QD3D11RenderTargetData *rtD = rtData(cmd.args.setRenderTarget.rt);
|
QD3D11RenderTargetData *rtD = rtData(cmd.args.setRenderTarget.rt);
|
||||||
context->OMSetRenderTargets(rtD->colorAttCount, rtD->colorAttCount ? rtD->rtv : nullptr, rtD->dsv);
|
context->OMSetRenderTargets(UINT(rtD->colorAttCount), rtD->colorAttCount ? rtD->rtv : nullptr, rtD->dsv);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case QD3D11CommandBuffer::Command::Clear:
|
case QD3D11CommandBuffer::Command::Clear:
|
||||||
@ -2048,7 +2110,7 @@ void QRhiD3D11::executeCommandBuffer(QD3D11CommandBuffer *cbD, QD3D11SwapChain *
|
|||||||
if (cmd.args.clear.mask & QD3D11CommandBuffer::Command::Stencil)
|
if (cmd.args.clear.mask & QD3D11CommandBuffer::Command::Stencil)
|
||||||
ds |= D3D11_CLEAR_STENCIL;
|
ds |= D3D11_CLEAR_STENCIL;
|
||||||
if (ds)
|
if (ds)
|
||||||
context->ClearDepthStencilView(rtD->dsv, ds, cmd.args.clear.d, cmd.args.clear.s);
|
context->ClearDepthStencilView(rtD->dsv, ds, cmd.args.clear.d, UINT8(cmd.args.clear.s));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case QD3D11CommandBuffer::Command::Viewport:
|
case QD3D11CommandBuffer::Command::Viewport:
|
||||||
@ -2078,8 +2140,8 @@ void QRhiD3D11::executeCommandBuffer(QD3D11CommandBuffer *cbD, QD3D11SwapChain *
|
|||||||
contextState.vsHighestActiveVertexBufferBinding = qMax<int>(
|
contextState.vsHighestActiveVertexBufferBinding = qMax<int>(
|
||||||
contextState.vsHighestActiveVertexBufferBinding,
|
contextState.vsHighestActiveVertexBufferBinding,
|
||||||
cmd.args.bindVertexBuffers.startSlot + cmd.args.bindVertexBuffers.slotCount - 1);
|
cmd.args.bindVertexBuffers.startSlot + cmd.args.bindVertexBuffers.slotCount - 1);
|
||||||
context->IASetVertexBuffers(cmd.args.bindVertexBuffers.startSlot,
|
context->IASetVertexBuffers(UINT(cmd.args.bindVertexBuffers.startSlot),
|
||||||
cmd.args.bindVertexBuffers.slotCount,
|
UINT(cmd.args.bindVertexBuffers.slotCount),
|
||||||
cmd.args.bindVertexBuffers.buffers,
|
cmd.args.bindVertexBuffers.buffers,
|
||||||
cmd.args.bindVertexBuffers.strides,
|
cmd.args.bindVertexBuffers.strides,
|
||||||
cmd.args.bindVertexBuffers.offsets);
|
cmd.args.bindVertexBuffers.offsets);
|
||||||
@ -2222,7 +2284,7 @@ static inline uint toD3DBufferUsage(QRhiBuffer::UsageFlags usage)
|
|||||||
u |= D3D11_BIND_CONSTANT_BUFFER;
|
u |= D3D11_BIND_CONSTANT_BUFFER;
|
||||||
if (usage.testFlag(QRhiBuffer::StorageBuffer))
|
if (usage.testFlag(QRhiBuffer::StorageBuffer))
|
||||||
u |= D3D11_BIND_UNORDERED_ACCESS;
|
u |= D3D11_BIND_UNORDERED_ACCESS;
|
||||||
return u;
|
return uint(u);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QD3D11Buffer::build()
|
bool QD3D11Buffer::build()
|
||||||
@ -2245,7 +2307,7 @@ bool QD3D11Buffer::build()
|
|||||||
|
|
||||||
D3D11_BUFFER_DESC desc;
|
D3D11_BUFFER_DESC desc;
|
||||||
memset(&desc, 0, sizeof(desc));
|
memset(&desc, 0, sizeof(desc));
|
||||||
desc.ByteWidth = roundedSize;
|
desc.ByteWidth = UINT(roundedSize);
|
||||||
desc.Usage = m_type == Dynamic ? D3D11_USAGE_DYNAMIC : D3D11_USAGE_DEFAULT;
|
desc.Usage = m_type == Dynamic ? D3D11_USAGE_DYNAMIC : D3D11_USAGE_DEFAULT;
|
||||||
desc.BindFlags = toD3DBufferUsage(m_usage);
|
desc.BindFlags = toD3DBufferUsage(m_usage);
|
||||||
desc.CPUAccessFlags = m_type == Dynamic ? D3D11_CPU_ACCESS_WRITE : 0;
|
desc.CPUAccessFlags = m_type == Dynamic ? D3D11_CPU_ACCESS_WRITE : 0;
|
||||||
@ -2264,10 +2326,10 @@ bool QD3D11Buffer::build()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!m_objectName.isEmpty())
|
if (!m_objectName.isEmpty())
|
||||||
buffer->SetPrivateData(WKPDID_D3DDebugObjectName, m_objectName.size(), m_objectName.constData());
|
buffer->SetPrivateData(WKPDID_D3DDebugObjectName, UINT(m_objectName.size()), m_objectName.constData());
|
||||||
|
|
||||||
QRHI_PROF;
|
QRHI_PROF;
|
||||||
QRHI_PROF_F(newBuffer(this, roundedSize, m_type == Dynamic ? 2 : 1, m_type == Dynamic ? 1 : 0));
|
QRHI_PROF_F(newBuffer(this, quint32(roundedSize), m_type == Dynamic ? 2 : 1, m_type == Dynamic ? 1 : 0));
|
||||||
|
|
||||||
generation += 1;
|
generation += 1;
|
||||||
rhiD->registerResource(this);
|
rhiD->registerResource(this);
|
||||||
@ -2285,7 +2347,7 @@ ID3D11UnorderedAccessView *QD3D11Buffer::unorderedAccessView()
|
|||||||
desc.Format = DXGI_FORMAT_R32_TYPELESS;
|
desc.Format = DXGI_FORMAT_R32_TYPELESS;
|
||||||
desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
|
desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
|
||||||
desc.Buffer.FirstElement = 0;
|
desc.Buffer.FirstElement = 0;
|
||||||
desc.Buffer.NumElements = aligned(m_size, 4) / 4;
|
desc.Buffer.NumElements = UINT(aligned(m_size, 4) / 4);
|
||||||
desc.Buffer.Flags = D3D11_BUFFER_UAV_FLAG_RAW;
|
desc.Buffer.Flags = D3D11_BUFFER_UAV_FLAG_RAW;
|
||||||
|
|
||||||
QRHI_RES_RHI(QRhiD3D11);
|
QRHI_RES_RHI(QRhiD3D11);
|
||||||
@ -2346,8 +2408,8 @@ bool QD3D11RenderBuffer::build()
|
|||||||
|
|
||||||
D3D11_TEXTURE2D_DESC desc;
|
D3D11_TEXTURE2D_DESC desc;
|
||||||
memset(&desc, 0, sizeof(desc));
|
memset(&desc, 0, sizeof(desc));
|
||||||
desc.Width = m_pixelSize.width();
|
desc.Width = UINT(m_pixelSize.width());
|
||||||
desc.Height = m_pixelSize.height();
|
desc.Height = UINT(m_pixelSize.height());
|
||||||
desc.MipLevels = 1;
|
desc.MipLevels = 1;
|
||||||
desc.ArraySize = 1;
|
desc.ArraySize = 1;
|
||||||
desc.SampleDesc = sampleDesc;
|
desc.SampleDesc = sampleDesc;
|
||||||
@ -2396,10 +2458,10 @@ bool QD3D11RenderBuffer::build()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!m_objectName.isEmpty())
|
if (!m_objectName.isEmpty())
|
||||||
tex->SetPrivateData(WKPDID_D3DDebugObjectName, m_objectName.size(), m_objectName.constData());
|
tex->SetPrivateData(WKPDID_D3DDebugObjectName, UINT(m_objectName.size()), m_objectName.constData());
|
||||||
|
|
||||||
QRHI_PROF;
|
QRHI_PROF;
|
||||||
QRHI_PROF_F(newRenderBuffer(this, false, false, sampleDesc.Count));
|
QRHI_PROF_F(newRenderBuffer(this, false, false, int(sampleDesc.Count)));
|
||||||
|
|
||||||
rhiD->registerResource(this);
|
rhiD->registerResource(this);
|
||||||
return true;
|
return true;
|
||||||
@ -2489,7 +2551,7 @@ bool QD3D11Texture::prepareBuild(QSize *adjustedSize)
|
|||||||
|
|
||||||
QRHI_RES_RHI(QRhiD3D11);
|
QRHI_RES_RHI(QRhiD3D11);
|
||||||
dxgiFormat = toD3DTextureFormat(m_format, m_flags);
|
dxgiFormat = toD3DTextureFormat(m_format, m_flags);
|
||||||
mipLevelCount = hasMipMaps ? rhiD->q->mipLevelsForSize(size) : 1;
|
mipLevelCount = uint(hasMipMaps ? rhiD->q->mipLevelsForSize(size) : 1);
|
||||||
sampleDesc = rhiD->effectiveSampleCount(m_sampleCount);
|
sampleDesc = rhiD->effectiveSampleCount(m_sampleCount);
|
||||||
if (sampleDesc.Count > 1) {
|
if (sampleDesc.Count > 1) {
|
||||||
if (isCube) {
|
if (isCube) {
|
||||||
@ -2575,8 +2637,8 @@ bool QD3D11Texture::build()
|
|||||||
|
|
||||||
D3D11_TEXTURE2D_DESC desc;
|
D3D11_TEXTURE2D_DESC desc;
|
||||||
memset(&desc, 0, sizeof(desc));
|
memset(&desc, 0, sizeof(desc));
|
||||||
desc.Width = size.width();
|
desc.Width = UINT(size.width());
|
||||||
desc.Height = size.height();
|
desc.Height = UINT(size.height());
|
||||||
desc.MipLevels = mipLevelCount;
|
desc.MipLevels = mipLevelCount;
|
||||||
desc.ArraySize = isCube ? 6 : 1;
|
desc.ArraySize = isCube ? 6 : 1;
|
||||||
desc.Format = dxgiFormat;
|
desc.Format = dxgiFormat;
|
||||||
@ -2596,10 +2658,10 @@ bool QD3D11Texture::build()
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!m_objectName.isEmpty())
|
if (!m_objectName.isEmpty())
|
||||||
tex->SetPrivateData(WKPDID_D3DDebugObjectName, m_objectName.size(), m_objectName.constData());
|
tex->SetPrivateData(WKPDID_D3DDebugObjectName, UINT(m_objectName.size()), m_objectName.constData());
|
||||||
|
|
||||||
QRHI_PROF;
|
QRHI_PROF;
|
||||||
QRHI_PROF_F(newTexture(this, true, mipLevelCount, isCube ? 6 : 1, sampleDesc.Count));
|
QRHI_PROF_F(newTexture(this, true, int(mipLevelCount), isCube ? 6 : 1, int(sampleDesc.Count)));
|
||||||
|
|
||||||
owns = true;
|
owns = true;
|
||||||
rhiD->registerResource(this);
|
rhiD->registerResource(this);
|
||||||
@ -2621,7 +2683,7 @@ bool QD3D11Texture::buildFrom(const QRhiNativeHandles *src)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
QRHI_PROF;
|
QRHI_PROF;
|
||||||
QRHI_PROF_F(newTexture(this, false, mipLevelCount, m_flags.testFlag(CubeMap) ? 6 : 1, sampleDesc.Count));
|
QRHI_PROF_F(newTexture(this, false, int(mipLevelCount), m_flags.testFlag(CubeMap) ? 6 : 1, int(sampleDesc.Count)));
|
||||||
|
|
||||||
owns = false;
|
owns = false;
|
||||||
QRHI_RES_RHI(QRhiD3D11);
|
QRHI_RES_RHI(QRhiD3D11);
|
||||||
@ -2645,12 +2707,12 @@ ID3D11UnorderedAccessView *QD3D11Texture::unorderedAccessViewForLevel(int level)
|
|||||||
desc.Format = dxgiFormat;
|
desc.Format = dxgiFormat;
|
||||||
if (isCube) {
|
if (isCube) {
|
||||||
desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY;
|
desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY;
|
||||||
desc.Texture2DArray.MipSlice = level;
|
desc.Texture2DArray.MipSlice = UINT(level);
|
||||||
desc.Texture2DArray.FirstArraySlice = 0;
|
desc.Texture2DArray.FirstArraySlice = 0;
|
||||||
desc.Texture2DArray.ArraySize = 6;
|
desc.Texture2DArray.ArraySize = 6;
|
||||||
} else {
|
} else {
|
||||||
desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
|
desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
|
||||||
desc.Texture2D.MipSlice = level;
|
desc.Texture2D.MipSlice = UINT(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
QRHI_RES_RHI(QRhiD3D11);
|
QRHI_RES_RHI(QRhiD3D11);
|
||||||
@ -2910,15 +2972,15 @@ bool QD3D11TextureRenderTarget::build()
|
|||||||
rtvDesc.Format = toD3DTextureFormat(texD->format(), texD->flags());
|
rtvDesc.Format = toD3DTextureFormat(texD->format(), texD->flags());
|
||||||
if (texD->flags().testFlag(QRhiTexture::CubeMap)) {
|
if (texD->flags().testFlag(QRhiTexture::CubeMap)) {
|
||||||
rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
|
rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
|
||||||
rtvDesc.Texture2DArray.MipSlice = colorAttachments[i].level();
|
rtvDesc.Texture2DArray.MipSlice = UINT(colorAttachments[i].level());
|
||||||
rtvDesc.Texture2DArray.FirstArraySlice = colorAttachments[i].layer();
|
rtvDesc.Texture2DArray.FirstArraySlice = UINT(colorAttachments[i].layer());
|
||||||
rtvDesc.Texture2DArray.ArraySize = 1;
|
rtvDesc.Texture2DArray.ArraySize = 1;
|
||||||
} else {
|
} else {
|
||||||
if (texD->sampleDesc.Count > 1) {
|
if (texD->sampleDesc.Count > 1) {
|
||||||
rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS;
|
rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS;
|
||||||
} else {
|
} else {
|
||||||
rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
|
rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
|
||||||
rtvDesc.Texture2D.MipSlice = colorAttachments[i].level();
|
rtvDesc.Texture2D.MipSlice = UINT(colorAttachments[i].level());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HRESULT hr = rhiD->dev->CreateRenderTargetView(texD->tex, &rtvDesc, &rtv[i]);
|
HRESULT hr = rhiD->dev->CreateRenderTargetView(texD->tex, &rtvDesc, &rtv[i]);
|
||||||
@ -2929,7 +2991,7 @@ bool QD3D11TextureRenderTarget::build()
|
|||||||
ownsRtv[i] = true;
|
ownsRtv[i] = true;
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
d.pixelSize = texD->pixelSize();
|
d.pixelSize = texD->pixelSize();
|
||||||
d.sampleCount = texD->sampleDesc.Count;
|
d.sampleCount = int(texD->sampleDesc.Count);
|
||||||
}
|
}
|
||||||
} else if (rb) {
|
} else if (rb) {
|
||||||
QD3D11RenderBuffer *rbD = QRHI_RES(QD3D11RenderBuffer, rb);
|
QD3D11RenderBuffer *rbD = QRHI_RES(QD3D11RenderBuffer, rb);
|
||||||
@ -2937,7 +2999,7 @@ bool QD3D11TextureRenderTarget::build()
|
|||||||
rtv[i] = rbD->rtv;
|
rtv[i] = rbD->rtv;
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
d.pixelSize = rbD->pixelSize();
|
d.pixelSize = rbD->pixelSize();
|
||||||
d.sampleCount = rbD->sampleDesc.Count;
|
d.sampleCount = int(rbD->sampleDesc.Count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2959,7 +3021,7 @@ bool QD3D11TextureRenderTarget::build()
|
|||||||
}
|
}
|
||||||
if (d.colorAttCount == 0) {
|
if (d.colorAttCount == 0) {
|
||||||
d.pixelSize = depthTexD->pixelSize();
|
d.pixelSize = depthTexD->pixelSize();
|
||||||
d.sampleCount = depthTexD->sampleDesc.Count;
|
d.sampleCount = int(depthTexD->sampleDesc.Count);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ownsDsv = false;
|
ownsDsv = false;
|
||||||
@ -2967,7 +3029,7 @@ bool QD3D11TextureRenderTarget::build()
|
|||||||
dsv = depthRbD->dsv;
|
dsv = depthRbD->dsv;
|
||||||
if (d.colorAttCount == 0) {
|
if (d.colorAttCount == 0) {
|
||||||
d.pixelSize = m_desc.depthStencilBuffer()->pixelSize();
|
d.pixelSize = m_desc.depthStencilBuffer()->pixelSize();
|
||||||
d.sampleCount = depthRbD->sampleDesc.Count;
|
d.sampleCount = int(depthRbD->sampleDesc.Count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
d.dsAttCount = 1;
|
d.dsAttCount = 1;
|
||||||
@ -3191,9 +3253,9 @@ static inline D3D11_PRIMITIVE_TOPOLOGY toD3DTopology(QRhiGraphicsPipeline::Topol
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint toD3DColorWriteMask(QRhiGraphicsPipeline::ColorMask c)
|
static inline UINT8 toD3DColorWriteMask(QRhiGraphicsPipeline::ColorMask c)
|
||||||
{
|
{
|
||||||
uint f = 0;
|
UINT8 f = 0;
|
||||||
if (c.testFlag(QRhiGraphicsPipeline::R))
|
if (c.testFlag(QRhiGraphicsPipeline::R))
|
||||||
f |= D3D11_COLOR_WRITE_ENABLE_RED;
|
f |= D3D11_COLOR_WRITE_ENABLE_RED;
|
||||||
if (c.testFlag(QRhiGraphicsPipeline::G))
|
if (c.testFlag(QRhiGraphicsPipeline::G))
|
||||||
@ -3328,22 +3390,22 @@ static QByteArray compileHlslShaderSource(const QShader &shader, QShader::Varian
|
|||||||
|
|
||||||
ID3DBlob *bytecode = nullptr;
|
ID3DBlob *bytecode = nullptr;
|
||||||
ID3DBlob *errors = nullptr;
|
ID3DBlob *errors = nullptr;
|
||||||
HRESULT hr = d3dCompile(hlslSource.shader().constData(), hlslSource.shader().size(),
|
HRESULT hr = d3dCompile(hlslSource.shader().constData(), SIZE_T(hlslSource.shader().size()),
|
||||||
nullptr, nullptr, nullptr,
|
nullptr, nullptr, nullptr,
|
||||||
hlslSource.entryPoint().constData(), target, 0, 0, &bytecode, &errors);
|
hlslSource.entryPoint().constData(), target, 0, 0, &bytecode, &errors);
|
||||||
if (FAILED(hr) || !bytecode) {
|
if (FAILED(hr) || !bytecode) {
|
||||||
qWarning("HLSL shader compilation failed: 0x%x", uint(hr));
|
qWarning("HLSL shader compilation failed: 0x%x", uint(hr));
|
||||||
if (errors) {
|
if (errors) {
|
||||||
*error = QString::fromUtf8(static_cast<const char *>(errors->GetBufferPointer()),
|
*error = QString::fromUtf8(static_cast<const char *>(errors->GetBufferPointer()),
|
||||||
errors->GetBufferSize());
|
int(errors->GetBufferSize()));
|
||||||
errors->Release();
|
errors->Release();
|
||||||
}
|
}
|
||||||
return QByteArray();
|
return QByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray result;
|
QByteArray result;
|
||||||
result.resize(bytecode->GetBufferSize());
|
result.resize(int(bytecode->GetBufferSize()));
|
||||||
memcpy(result.data(), bytecode->GetBufferPointer(), result.size());
|
memcpy(result.data(), bytecode->GetBufferPointer(), size_t(result.size()));
|
||||||
bytecode->Release();
|
bytecode->Release();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -3375,8 +3437,8 @@ bool QD3D11GraphicsPipeline::build()
|
|||||||
dsDesc.DepthFunc = toD3DCompareOp(m_depthOp);
|
dsDesc.DepthFunc = toD3DCompareOp(m_depthOp);
|
||||||
dsDesc.StencilEnable = m_stencilTest;
|
dsDesc.StencilEnable = m_stencilTest;
|
||||||
if (m_stencilTest) {
|
if (m_stencilTest) {
|
||||||
dsDesc.StencilReadMask = m_stencilReadMask;
|
dsDesc.StencilReadMask = UINT8(m_stencilReadMask);
|
||||||
dsDesc.StencilWriteMask = m_stencilWriteMask;
|
dsDesc.StencilWriteMask = UINT8(m_stencilWriteMask);
|
||||||
dsDesc.FrontFace.StencilFailOp = toD3DStencilOp(m_stencilFront.failOp);
|
dsDesc.FrontFace.StencilFailOp = toD3DStencilOp(m_stencilFront.failOp);
|
||||||
dsDesc.FrontFace.StencilDepthFailOp = toD3DStencilOp(m_stencilFront.depthFailOp);
|
dsDesc.FrontFace.StencilDepthFailOp = toD3DStencilOp(m_stencilFront.depthFailOp);
|
||||||
dsDesc.FrontFace.StencilPassOp = toD3DStencilOp(m_stencilFront.passOp);
|
dsDesc.FrontFace.StencilPassOp = toD3DStencilOp(m_stencilFront.passOp);
|
||||||
@ -3453,7 +3515,7 @@ bool QD3D11GraphicsPipeline::build()
|
|||||||
|
|
||||||
switch (shaderStage.type()) {
|
switch (shaderStage.type()) {
|
||||||
case QRhiShaderStage::Vertex:
|
case QRhiShaderStage::Vertex:
|
||||||
hr = rhiD->dev->CreateVertexShader(bytecode.constData(), bytecode.size(), nullptr, &vs);
|
hr = rhiD->dev->CreateVertexShader(bytecode.constData(), SIZE_T(bytecode.size()), nullptr, &vs);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
qWarning("Failed to create vertex shader: %s", qPrintable(comErrorMessage(hr)));
|
qWarning("Failed to create vertex shader: %s", qPrintable(comErrorMessage(hr)));
|
||||||
return false;
|
return false;
|
||||||
@ -3463,7 +3525,7 @@ bool QD3D11GraphicsPipeline::build()
|
|||||||
vs->AddRef();
|
vs->AddRef();
|
||||||
break;
|
break;
|
||||||
case QRhiShaderStage::Fragment:
|
case QRhiShaderStage::Fragment:
|
||||||
hr = rhiD->dev->CreatePixelShader(bytecode.constData(), bytecode.size(), nullptr, &fs);
|
hr = rhiD->dev->CreatePixelShader(bytecode.constData(), SIZE_T(bytecode.size()), nullptr, &fs);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
qWarning("Failed to create pixel shader: %s", qPrintable(comErrorMessage(hr)));
|
qWarning("Failed to create pixel shader: %s", qPrintable(comErrorMessage(hr)));
|
||||||
return false;
|
return false;
|
||||||
@ -3488,20 +3550,21 @@ bool QD3D11GraphicsPipeline::build()
|
|||||||
memset(&desc, 0, sizeof(desc));
|
memset(&desc, 0, sizeof(desc));
|
||||||
// the output from SPIRV-Cross uses TEXCOORD<location> as the semantic
|
// the output from SPIRV-Cross uses TEXCOORD<location> as the semantic
|
||||||
desc.SemanticName = "TEXCOORD";
|
desc.SemanticName = "TEXCOORD";
|
||||||
desc.SemanticIndex = attribute.location();
|
desc.SemanticIndex = UINT(attribute.location());
|
||||||
desc.Format = toD3DAttributeFormat(attribute.format());
|
desc.Format = toD3DAttributeFormat(attribute.format());
|
||||||
desc.InputSlot = attribute.binding();
|
desc.InputSlot = UINT(attribute.binding());
|
||||||
desc.AlignedByteOffset = attribute.offset();
|
desc.AlignedByteOffset = attribute.offset();
|
||||||
const QRhiVertexInputBinding &binding(bindings[attribute.binding()]);
|
const QRhiVertexInputBinding &binding(bindings[attribute.binding()]);
|
||||||
if (binding.classification() == QRhiVertexInputBinding::PerInstance) {
|
if (binding.classification() == QRhiVertexInputBinding::PerInstance) {
|
||||||
desc.InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA;
|
desc.InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA;
|
||||||
desc.InstanceDataStepRate = binding.instanceStepRate();
|
desc.InstanceDataStepRate = UINT(binding.instanceStepRate());
|
||||||
} else {
|
} else {
|
||||||
desc.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
|
desc.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
|
||||||
}
|
}
|
||||||
inputDescs.append(desc);
|
inputDescs.append(desc);
|
||||||
}
|
}
|
||||||
hr = rhiD->dev->CreateInputLayout(inputDescs.constData(), inputDescs.count(), vsByteCode, vsByteCode.size(), &inputLayout);
|
hr = rhiD->dev->CreateInputLayout(inputDescs.constData(), UINT(inputDescs.count()),
|
||||||
|
vsByteCode, SIZE_T(vsByteCode.size()), &inputLayout);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
qWarning("Failed to create input layout: %s", qPrintable(comErrorMessage(hr)));
|
qWarning("Failed to create input layout: %s", qPrintable(comErrorMessage(hr)));
|
||||||
return false;
|
return false;
|
||||||
@ -3554,7 +3617,7 @@ bool QD3D11ComputePipeline::build()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT hr = rhiD->dev->CreateComputeShader(bytecode.constData(), bytecode.size(), nullptr, &cs);
|
HRESULT hr = rhiD->dev->CreateComputeShader(bytecode.constData(), SIZE_T(bytecode.size()), nullptr, &cs);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
qWarning("Failed to create compute shader: %s", qPrintable(comErrorMessage(hr)));
|
qWarning("Failed to create compute shader: %s", qPrintable(comErrorMessage(hr)));
|
||||||
return false;
|
return false;
|
||||||
@ -3690,8 +3753,8 @@ bool QD3D11SwapChain::newColorBuffer(const QSize &size, DXGI_FORMAT format, DXGI
|
|||||||
{
|
{
|
||||||
D3D11_TEXTURE2D_DESC desc;
|
D3D11_TEXTURE2D_DESC desc;
|
||||||
memset(&desc, 0, sizeof(desc));
|
memset(&desc, 0, sizeof(desc));
|
||||||
desc.Width = size.width();
|
desc.Width = UINT(size.width());
|
||||||
desc.Height = size.height();
|
desc.Height = UINT(size.height());
|
||||||
desc.MipLevels = 1;
|
desc.MipLevels = 1;
|
||||||
desc.ArraySize = 1;
|
desc.ArraySize = 1;
|
||||||
desc.Format = format;
|
desc.Format = format;
|
||||||
@ -3747,11 +3810,23 @@ bool QD3D11SwapChain::buildOrResize()
|
|||||||
const UINT swapChainFlags = 0;
|
const UINT swapChainFlags = 0;
|
||||||
|
|
||||||
QRHI_RES_RHI(QRhiD3D11);
|
QRHI_RES_RHI(QRhiD3D11);
|
||||||
const bool useFlipDiscard = rhiD->hasDxgi2 && rhiD->supportsFlipDiscardSwapchain;
|
bool useFlipDiscard = rhiD->hasDxgi2 && rhiD->supportsFlipDiscardSwapchain;
|
||||||
if (!swapChain) {
|
if (!swapChain) {
|
||||||
HWND hwnd = reinterpret_cast<HWND>(window->winId());
|
HWND hwnd = reinterpret_cast<HWND>(window->winId());
|
||||||
sampleDesc = rhiD->effectiveSampleCount(m_sampleCount);
|
sampleDesc = rhiD->effectiveSampleCount(m_sampleCount);
|
||||||
|
|
||||||
|
// Take a shortcut for alpha: our QWindow is OpenGLSurface so whatever
|
||||||
|
// the platform plugin does to enable transparency for OpenGL window
|
||||||
|
// will be sufficient for us too on the legacy (DISCARD) path. For
|
||||||
|
// FLIP_DISCARD we'd need to use DirectComposition (create a
|
||||||
|
// IDCompositionDevice/Target/Visual), avoid that for now.
|
||||||
|
if (m_flags.testFlag(SurfaceHasPreMulAlpha) || m_flags.testFlag(SurfaceHasNonPreMulAlpha)) {
|
||||||
|
useFlipDiscard = false;
|
||||||
|
if (window->requestedFormat().alphaBufferSize() <= 0)
|
||||||
|
qWarning("Swapchain says surface has alpha but the window has no alphaBufferSize set. "
|
||||||
|
"This may lead to problems.");
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
if (useFlipDiscard) {
|
if (useFlipDiscard) {
|
||||||
// We use FLIP_DISCARD which implies a buffer count of 2 (as opposed to the
|
// We use FLIP_DISCARD which implies a buffer count of 2 (as opposed to the
|
||||||
@ -3762,18 +3837,17 @@ bool QD3D11SwapChain::buildOrResize()
|
|||||||
|
|
||||||
DXGI_SWAP_CHAIN_DESC1 desc;
|
DXGI_SWAP_CHAIN_DESC1 desc;
|
||||||
memset(&desc, 0, sizeof(desc));
|
memset(&desc, 0, sizeof(desc));
|
||||||
desc.Width = pixelSize.width();
|
desc.Width = UINT(pixelSize.width());
|
||||||
desc.Height = pixelSize.height();
|
desc.Height = UINT(pixelSize.height());
|
||||||
desc.Format = colorFormat;
|
desc.Format = colorFormat;
|
||||||
desc.SampleDesc.Count = 1;
|
desc.SampleDesc.Count = 1;
|
||||||
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||||
desc.BufferCount = BUFFER_COUNT;
|
desc.BufferCount = BUFFER_COUNT;
|
||||||
desc.Scaling = DXGI_SCALING_STRETCH;
|
desc.Scaling = DXGI_SCALING_STRETCH;
|
||||||
desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||||
if (m_flags.testFlag(SurfaceHasPreMulAlpha))
|
// Do not bother with AlphaMode, if won't work unless we go through
|
||||||
desc.AlphaMode = DXGI_ALPHA_MODE_PREMULTIPLIED;
|
// DirectComposition. Instead, we just take the other (DISCARD)
|
||||||
else if (m_flags.testFlag(SurfaceHasNonPreMulAlpha))
|
// path for now when alpha is requested.
|
||||||
desc.AlphaMode = DXGI_ALPHA_MODE_STRAIGHT;
|
|
||||||
desc.Flags = swapChainFlags;
|
desc.Flags = swapChainFlags;
|
||||||
|
|
||||||
IDXGISwapChain1 *sc1;
|
IDXGISwapChain1 *sc1;
|
||||||
@ -3788,8 +3862,8 @@ bool QD3D11SwapChain::buildOrResize()
|
|||||||
|
|
||||||
DXGI_SWAP_CHAIN_DESC desc;
|
DXGI_SWAP_CHAIN_DESC desc;
|
||||||
memset(&desc, 0, sizeof(desc));
|
memset(&desc, 0, sizeof(desc));
|
||||||
desc.BufferDesc.Width = pixelSize.width();
|
desc.BufferDesc.Width = UINT(pixelSize.width());
|
||||||
desc.BufferDesc.Height = pixelSize.height();
|
desc.BufferDesc.Height = UINT(pixelSize.height());
|
||||||
desc.BufferDesc.RefreshRate.Numerator = 60;
|
desc.BufferDesc.RefreshRate.Numerator = 60;
|
||||||
desc.BufferDesc.RefreshRate.Denominator = 1;
|
desc.BufferDesc.RefreshRate.Denominator = 1;
|
||||||
desc.BufferDesc.Format = colorFormat;
|
desc.BufferDesc.Format = colorFormat;
|
||||||
@ -3811,9 +3885,13 @@ bool QD3D11SwapChain::buildOrResize()
|
|||||||
} else {
|
} else {
|
||||||
releaseBuffers();
|
releaseBuffers();
|
||||||
const UINT count = useFlipDiscard ? BUFFER_COUNT : 1;
|
const UINT count = useFlipDiscard ? BUFFER_COUNT : 1;
|
||||||
HRESULT hr = swapChain->ResizeBuffers(count, pixelSize.width(), pixelSize.height(),
|
HRESULT hr = swapChain->ResizeBuffers(count, UINT(pixelSize.width()), UINT(pixelSize.height()),
|
||||||
colorFormat, swapChainFlags);
|
colorFormat, swapChainFlags);
|
||||||
if (FAILED(hr)) {
|
if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET) {
|
||||||
|
qWarning("Device loss detected in ResizeBuffers()");
|
||||||
|
rhiD->deviceLost = true;
|
||||||
|
return false;
|
||||||
|
} else if (FAILED(hr)) {
|
||||||
qWarning("Failed to resize D3D11 swapchain: %s", qPrintable(comErrorMessage(hr)));
|
qWarning("Failed to resize D3D11 swapchain: %s", qPrintable(comErrorMessage(hr)));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -3874,13 +3952,13 @@ bool QD3D11SwapChain::buildOrResize()
|
|||||||
QD3D11ReferenceRenderTarget *rtD = QRHI_RES(QD3D11ReferenceRenderTarget, &rt);
|
QD3D11ReferenceRenderTarget *rtD = QRHI_RES(QD3D11ReferenceRenderTarget, &rt);
|
||||||
rtD->d.rp = QRHI_RES(QD3D11RenderPassDescriptor, m_renderPassDesc);
|
rtD->d.rp = QRHI_RES(QD3D11RenderPassDescriptor, m_renderPassDesc);
|
||||||
rtD->d.pixelSize = pixelSize;
|
rtD->d.pixelSize = pixelSize;
|
||||||
rtD->d.dpr = window->devicePixelRatio();
|
rtD->d.dpr = float(window->devicePixelRatio());
|
||||||
rtD->d.sampleCount = sampleDesc.Count;
|
rtD->d.sampleCount = int(sampleDesc.Count);
|
||||||
rtD->d.colorAttCount = 1;
|
rtD->d.colorAttCount = 1;
|
||||||
rtD->d.dsAttCount = m_depthStencil ? 1 : 0;
|
rtD->d.dsAttCount = m_depthStencil ? 1 : 0;
|
||||||
|
|
||||||
QRHI_PROF;
|
QRHI_PROF;
|
||||||
QRHI_PROF_F(resizeSwapChain(this, BUFFER_COUNT, sampleDesc.Count > 1 ? BUFFER_COUNT : 0, sampleDesc.Count));
|
QRHI_PROF_F(resizeSwapChain(this, BUFFER_COUNT, sampleDesc.Count > 1 ? BUFFER_COUNT : 0, int(sampleDesc.Count)));
|
||||||
if (rhiP) {
|
if (rhiP) {
|
||||||
D3D11_QUERY_DESC queryDesc;
|
D3D11_QUERY_DESC queryDesc;
|
||||||
memset(&queryDesc, 0, sizeof(queryDesc));
|
memset(&queryDesc, 0, sizeof(queryDesc));
|
||||||
@ -3914,4 +3992,34 @@ bool QD3D11SwapChain::buildOrResize()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QRhiD3D11::DeviceCurse::initResources()
|
||||||
|
{
|
||||||
|
framesLeft = framesToActivate;
|
||||||
|
|
||||||
|
HRESULT hr = q->dev->CreateComputeShader(g_killDeviceByTimingOut, sizeof(g_killDeviceByTimingOut), nullptr, &cs);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
qWarning("Failed to create compute shader: %s", qPrintable(comErrorMessage(hr)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QRhiD3D11::DeviceCurse::releaseResources()
|
||||||
|
{
|
||||||
|
if (cs) {
|
||||||
|
cs->Release();
|
||||||
|
cs = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QRhiD3D11::DeviceCurse::activate()
|
||||||
|
{
|
||||||
|
if (!cs)
|
||||||
|
return;
|
||||||
|
|
||||||
|
qDebug("Activating Curse. Goodbye Cruel World.");
|
||||||
|
|
||||||
|
q->context->CSSetShader(cs, nullptr, 0);
|
||||||
|
q->context->Dispatch(256, 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -58,6 +58,9 @@ QT_BEGIN_NAMESPACE
|
|||||||
struct Q_GUI_EXPORT QRhiD3D11InitParams : public QRhiInitParams
|
struct Q_GUI_EXPORT QRhiD3D11InitParams : public QRhiInitParams
|
||||||
{
|
{
|
||||||
bool enableDebugLayer = false;
|
bool enableDebugLayer = false;
|
||||||
|
|
||||||
|
int framesUntilKillingDeviceViaTdr = -1;
|
||||||
|
bool repeatDeviceKill = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Q_GUI_EXPORT QRhiD3D11NativeHandles : public QRhiNativeHandles
|
struct Q_GUI_EXPORT QRhiD3D11NativeHandles : public QRhiNativeHandles
|
||||||
|
@ -631,8 +631,9 @@ public:
|
|||||||
int resourceLimit(QRhi::ResourceLimit limit) const override;
|
int resourceLimit(QRhi::ResourceLimit limit) const override;
|
||||||
const QRhiNativeHandles *nativeHandles() override;
|
const QRhiNativeHandles *nativeHandles() override;
|
||||||
void sendVMemStatsToProfiler() override;
|
void sendVMemStatsToProfiler() override;
|
||||||
void makeThreadLocalNativeContextCurrent() override;
|
bool makeThreadLocalNativeContextCurrent() override;
|
||||||
void releaseCachedResources() override;
|
void releaseCachedResources() override;
|
||||||
|
bool isDeviceLost() const override;
|
||||||
|
|
||||||
void enqueueSubresUpload(QD3D11Texture *texD, QD3D11CommandBuffer *cbD,
|
void enqueueSubresUpload(QD3D11Texture *texD, QD3D11CommandBuffer *cbD,
|
||||||
int layer, int level, const QRhiTextureSubresourceUploadDescription &subresDesc);
|
int layer, int level, const QRhiTextureSubresourceUploadDescription &subresDesc);
|
||||||
@ -658,6 +659,7 @@ public:
|
|||||||
IDXGIFactory1 *dxgiFactory = nullptr;
|
IDXGIFactory1 *dxgiFactory = nullptr;
|
||||||
bool hasDxgi2 = false;
|
bool hasDxgi2 = false;
|
||||||
bool supportsFlipDiscardSwapchain = false;
|
bool supportsFlipDiscardSwapchain = false;
|
||||||
|
bool deviceLost = false;
|
||||||
QRhiD3D11NativeHandles nativeHandlesStruct;
|
QRhiD3D11NativeHandles nativeHandlesStruct;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
@ -694,6 +696,19 @@ public:
|
|||||||
QByteArray bytecode;
|
QByteArray bytecode;
|
||||||
};
|
};
|
||||||
QHash<QRhiShaderStage, Shader> m_shaderCache;
|
QHash<QRhiShaderStage, Shader> m_shaderCache;
|
||||||
|
|
||||||
|
struct DeviceCurse {
|
||||||
|
DeviceCurse(QRhiD3D11 *impl) : q(impl) { }
|
||||||
|
QRhiD3D11 *q;
|
||||||
|
int framesToActivate = -1;
|
||||||
|
bool permanent = false;
|
||||||
|
int framesLeft = 0;
|
||||||
|
ID3D11ComputeShader *cs = nullptr;
|
||||||
|
|
||||||
|
void initResources();
|
||||||
|
void releaseResources();
|
||||||
|
void activate();
|
||||||
|
} deviceCurse;
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_TYPEINFO(QRhiD3D11::ActiveReadback, Q_MOVABLE_TYPE);
|
Q_DECLARE_TYPEINFO(QRhiD3D11::ActiveReadback, Q_MOVABLE_TYPE);
|
||||||
|
@ -371,7 +371,12 @@ bool QRhiGles2::ensureContext(QSurface *surface) const
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (!ctx->makeCurrent(surface)) {
|
if (!ctx->makeCurrent(surface)) {
|
||||||
qWarning("QRhiGles2: Failed to make context current. Expect bad things to happen.");
|
if (ctx->isValid()) {
|
||||||
|
qWarning("QRhiGles2: Failed to make context current. Expect bad things to happen.");
|
||||||
|
} else {
|
||||||
|
qWarning("QRhiGles2: Context is lost.");
|
||||||
|
contextLost = true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -491,6 +496,8 @@ bool QRhiGles2::create(QRhi::Flags flags)
|
|||||||
|
|
||||||
nativeHandlesStruct.context = ctx;
|
nativeHandlesStruct.context = ctx;
|
||||||
|
|
||||||
|
contextLost = false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -654,7 +661,7 @@ static inline GLenum toGlCompressedTextureFormat(QRhiTexture::Format format, QRh
|
|||||||
bool QRhiGles2::isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags) const
|
bool QRhiGles2::isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags) const
|
||||||
{
|
{
|
||||||
if (isCompressedFormat(format))
|
if (isCompressedFormat(format))
|
||||||
return supportedCompressedFormats.contains(toGlCompressedTextureFormat(format, flags));
|
return supportedCompressedFormats.contains(GLint(toGlCompressedTextureFormat(format, flags)));
|
||||||
|
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case QRhiTexture::D16:
|
case QRhiTexture::D16:
|
||||||
@ -753,12 +760,12 @@ void QRhiGles2::sendVMemStatsToProfiler()
|
|||||||
// nothing to do here
|
// nothing to do here
|
||||||
}
|
}
|
||||||
|
|
||||||
void QRhiGles2::makeThreadLocalNativeContextCurrent()
|
bool QRhiGles2::makeThreadLocalNativeContextCurrent()
|
||||||
{
|
{
|
||||||
if (inFrame && !ofr.active)
|
if (inFrame && !ofr.active)
|
||||||
ensureContext(currentSwapChain->surface);
|
return ensureContext(currentSwapChain->surface);
|
||||||
else
|
else
|
||||||
ensureContext();
|
return ensureContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QRhiGles2::releaseCachedResources()
|
void QRhiGles2::releaseCachedResources()
|
||||||
@ -772,6 +779,11 @@ void QRhiGles2::releaseCachedResources()
|
|||||||
m_shaderCache.clear();
|
m_shaderCache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QRhiGles2::isDeviceLost() const
|
||||||
|
{
|
||||||
|
return contextLost;
|
||||||
|
}
|
||||||
|
|
||||||
QRhiRenderBuffer *QRhiGles2::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
|
QRhiRenderBuffer *QRhiGles2::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
|
||||||
int sampleCount, QRhiRenderBuffer::Flags flags)
|
int sampleCount, QRhiRenderBuffer::Flags flags)
|
||||||
{
|
{
|
||||||
@ -930,7 +942,7 @@ void QRhiGles2::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind
|
|||||||
uint *p = cmd.args.bindShaderResources.dynamicOffsetPairs;
|
uint *p = cmd.args.bindShaderResources.dynamicOffsetPairs;
|
||||||
for (int i = 0; i < dynamicOffsetCount; ++i) {
|
for (int i = 0; i < dynamicOffsetCount; ++i) {
|
||||||
const QRhiCommandBuffer::DynamicOffset &dynOfs(dynamicOffsets[i]);
|
const QRhiCommandBuffer::DynamicOffset &dynOfs(dynamicOffsets[i]);
|
||||||
*p++ = dynOfs.first;
|
*p++ = uint(dynOfs.first);
|
||||||
*p++ = dynOfs.second;
|
*p++ = dynOfs.second;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1023,10 +1035,10 @@ void QRhiGles2::setBlendConstants(QRhiCommandBuffer *cb, const QColor &c)
|
|||||||
|
|
||||||
QGles2CommandBuffer::Command cmd;
|
QGles2CommandBuffer::Command cmd;
|
||||||
cmd.cmd = QGles2CommandBuffer::Command::BlendConstants;
|
cmd.cmd = QGles2CommandBuffer::Command::BlendConstants;
|
||||||
cmd.args.blendConstants.r = c.redF();
|
cmd.args.blendConstants.r = float(c.redF());
|
||||||
cmd.args.blendConstants.g = c.greenF();
|
cmd.args.blendConstants.g = float(c.greenF());
|
||||||
cmd.args.blendConstants.b = c.blueF();
|
cmd.args.blendConstants.b = float(c.blueF());
|
||||||
cmd.args.blendConstants.a = c.alphaF();
|
cmd.args.blendConstants.a = float(c.alphaF());
|
||||||
cbD->commands.append(cmd);
|
cbD->commands.append(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1156,7 +1168,7 @@ QRhi::FrameOpResult QRhiGles2::beginFrame(QRhiSwapChain *swapChain, QRhi::BeginF
|
|||||||
|
|
||||||
QGles2SwapChain *swapChainD = QRHI_RES(QGles2SwapChain, swapChain);
|
QGles2SwapChain *swapChainD = QRHI_RES(QGles2SwapChain, swapChain);
|
||||||
if (!ensureContext(swapChainD->surface))
|
if (!ensureContext(swapChainD->surface))
|
||||||
return QRhi::FrameOpError;
|
return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
|
||||||
|
|
||||||
currentSwapChain = swapChainD;
|
currentSwapChain = swapChainD;
|
||||||
|
|
||||||
@ -1179,7 +1191,7 @@ QRhi::FrameOpResult QRhiGles2::endFrame(QRhiSwapChain *swapChain, QRhi::EndFrame
|
|||||||
addBoundaryCommand(&swapChainD->cb, QGles2CommandBuffer::Command::EndFrame);
|
addBoundaryCommand(&swapChainD->cb, QGles2CommandBuffer::Command::EndFrame);
|
||||||
|
|
||||||
if (!ensureContext(swapChainD->surface))
|
if (!ensureContext(swapChainD->surface))
|
||||||
return QRhi::FrameOpError;
|
return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
|
||||||
|
|
||||||
executeCommandBuffer(&swapChainD->cb);
|
executeCommandBuffer(&swapChainD->cb);
|
||||||
|
|
||||||
@ -1203,7 +1215,7 @@ QRhi::FrameOpResult QRhiGles2::beginOffscreenFrame(QRhiCommandBuffer **cb, QRhi:
|
|||||||
{
|
{
|
||||||
Q_UNUSED(flags);
|
Q_UNUSED(flags);
|
||||||
if (!ensureContext())
|
if (!ensureContext())
|
||||||
return QRhi::FrameOpError;
|
return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
|
||||||
|
|
||||||
ofr.active = true;
|
ofr.active = true;
|
||||||
|
|
||||||
@ -1225,7 +1237,7 @@ QRhi::FrameOpResult QRhiGles2::endOffscreenFrame(QRhi::EndFrameFlags flags)
|
|||||||
addBoundaryCommand(&ofr.cbWrapper, QGles2CommandBuffer::Command::EndFrame);
|
addBoundaryCommand(&ofr.cbWrapper, QGles2CommandBuffer::Command::EndFrame);
|
||||||
|
|
||||||
if (!ensureContext())
|
if (!ensureContext())
|
||||||
return QRhi::FrameOpError;
|
return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
|
||||||
|
|
||||||
executeCommandBuffer(&ofr.cbWrapper);
|
executeCommandBuffer(&ofr.cbWrapper);
|
||||||
|
|
||||||
@ -1239,14 +1251,14 @@ QRhi::FrameOpResult QRhiGles2::finish()
|
|||||||
Q_ASSERT(!currentSwapChain);
|
Q_ASSERT(!currentSwapChain);
|
||||||
Q_ASSERT(ofr.cbWrapper.recordingPass == QGles2CommandBuffer::NoPass);
|
Q_ASSERT(ofr.cbWrapper.recordingPass == QGles2CommandBuffer::NoPass);
|
||||||
if (!ensureContext())
|
if (!ensureContext())
|
||||||
return QRhi::FrameOpError;
|
return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
|
||||||
executeCommandBuffer(&ofr.cbWrapper);
|
executeCommandBuffer(&ofr.cbWrapper);
|
||||||
ofr.cbWrapper.resetCommands();
|
ofr.cbWrapper.resetCommands();
|
||||||
} else {
|
} else {
|
||||||
Q_ASSERT(currentSwapChain);
|
Q_ASSERT(currentSwapChain);
|
||||||
Q_ASSERT(currentSwapChain->cb.recordingPass == QGles2CommandBuffer::NoPass);
|
Q_ASSERT(currentSwapChain->cb.recordingPass == QGles2CommandBuffer::NoPass);
|
||||||
if (!ensureContext(currentSwapChain->surface))
|
if (!ensureContext(currentSwapChain->surface))
|
||||||
return QRhi::FrameOpError;
|
return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
|
||||||
executeCommandBuffer(¤tSwapChain->cb);
|
executeCommandBuffer(¤tSwapChain->cb);
|
||||||
currentSwapChain->cb.resetCommands();
|
currentSwapChain->cb.resetCommands();
|
||||||
}
|
}
|
||||||
@ -1314,7 +1326,7 @@ void QRhiGles2::enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cb
|
|||||||
}
|
}
|
||||||
cmd.args.subImage.target = texD->target;
|
cmd.args.subImage.target = texD->target;
|
||||||
cmd.args.subImage.texture = texD->texture;
|
cmd.args.subImage.texture = texD->texture;
|
||||||
cmd.args.subImage.faceTarget = faceTargetBase + layer;
|
cmd.args.subImage.faceTarget = faceTargetBase + uint(layer);
|
||||||
cmd.args.subImage.level = level;
|
cmd.args.subImage.level = level;
|
||||||
cmd.args.subImage.dx = dp.x();
|
cmd.args.subImage.dx = dp.x();
|
||||||
cmd.args.subImage.dy = dp.y();
|
cmd.args.subImage.dy = dp.y();
|
||||||
@ -1333,7 +1345,7 @@ void QRhiGles2::enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cb
|
|||||||
cmd.cmd = QGles2CommandBuffer::Command::CompressedSubImage;
|
cmd.cmd = QGles2CommandBuffer::Command::CompressedSubImage;
|
||||||
cmd.args.compressedSubImage.target = texD->target;
|
cmd.args.compressedSubImage.target = texD->target;
|
||||||
cmd.args.compressedSubImage.texture = texD->texture;
|
cmd.args.compressedSubImage.texture = texD->texture;
|
||||||
cmd.args.compressedSubImage.faceTarget = faceTargetBase + layer;
|
cmd.args.compressedSubImage.faceTarget = faceTargetBase + uint(layer);
|
||||||
cmd.args.compressedSubImage.level = level;
|
cmd.args.compressedSubImage.level = level;
|
||||||
cmd.args.compressedSubImage.dx = dp.x();
|
cmd.args.compressedSubImage.dx = dp.x();
|
||||||
cmd.args.compressedSubImage.dy = dp.y();
|
cmd.args.compressedSubImage.dy = dp.y();
|
||||||
@ -1348,7 +1360,7 @@ void QRhiGles2::enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cb
|
|||||||
cmd.cmd = QGles2CommandBuffer::Command::CompressedImage;
|
cmd.cmd = QGles2CommandBuffer::Command::CompressedImage;
|
||||||
cmd.args.compressedImage.target = texD->target;
|
cmd.args.compressedImage.target = texD->target;
|
||||||
cmd.args.compressedImage.texture = texD->texture;
|
cmd.args.compressedImage.texture = texD->texture;
|
||||||
cmd.args.compressedImage.faceTarget = faceTargetBase + layer;
|
cmd.args.compressedImage.faceTarget = faceTargetBase + uint(layer);
|
||||||
cmd.args.compressedImage.level = level;
|
cmd.args.compressedImage.level = level;
|
||||||
cmd.args.compressedImage.glintformat = texD->glintformat;
|
cmd.args.compressedImage.glintformat = texD->glintformat;
|
||||||
cmd.args.compressedImage.w = size.width();
|
cmd.args.compressedImage.w = size.width();
|
||||||
@ -1366,7 +1378,7 @@ void QRhiGles2::enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cb
|
|||||||
cmd.cmd = QGles2CommandBuffer::Command::SubImage;
|
cmd.cmd = QGles2CommandBuffer::Command::SubImage;
|
||||||
cmd.args.subImage.target = texD->target;
|
cmd.args.subImage.target = texD->target;
|
||||||
cmd.args.subImage.texture = texD->texture;
|
cmd.args.subImage.texture = texD->texture;
|
||||||
cmd.args.subImage.faceTarget = faceTargetBase + layer;
|
cmd.args.subImage.faceTarget = faceTargetBase + uint(layer);
|
||||||
cmd.args.subImage.level = level;
|
cmd.args.subImage.level = level;
|
||||||
cmd.args.subImage.dx = dp.x();
|
cmd.args.subImage.dx = dp.x();
|
||||||
cmd.args.subImage.dy = dp.y();
|
cmd.args.subImage.dy = dp.y();
|
||||||
@ -1394,7 +1406,7 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
|
|||||||
QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, u.buf);
|
QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, u.buf);
|
||||||
Q_ASSERT(bufD->m_type == QRhiBuffer::Dynamic);
|
Q_ASSERT(bufD->m_type == QRhiBuffer::Dynamic);
|
||||||
if (bufD->m_usage.testFlag(QRhiBuffer::UniformBuffer)) {
|
if (bufD->m_usage.testFlag(QRhiBuffer::UniformBuffer)) {
|
||||||
memcpy(bufD->ubuf.data() + u.offset, u.data.constData(), u.data.size());
|
memcpy(bufD->ubuf.data() + u.offset, u.data.constData(), size_t(u.data.size()));
|
||||||
} else {
|
} else {
|
||||||
trackedBufferBarrier(cbD, bufD, QGles2Buffer::AccessUpdate);
|
trackedBufferBarrier(cbD, bufD, QGles2Buffer::AccessUpdate);
|
||||||
QGles2CommandBuffer::Command cmd;
|
QGles2CommandBuffer::Command cmd;
|
||||||
@ -1413,7 +1425,7 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
|
|||||||
Q_ASSERT(bufD->m_type != QRhiBuffer::Dynamic);
|
Q_ASSERT(bufD->m_type != QRhiBuffer::Dynamic);
|
||||||
Q_ASSERT(u.offset + u.data.size() <= bufD->m_size);
|
Q_ASSERT(u.offset + u.data.size() <= bufD->m_size);
|
||||||
if (bufD->m_usage.testFlag(QRhiBuffer::UniformBuffer)) {
|
if (bufD->m_usage.testFlag(QRhiBuffer::UniformBuffer)) {
|
||||||
memcpy(bufD->ubuf.data() + u.offset, u.data.constData(), u.data.size());
|
memcpy(bufD->ubuf.data() + u.offset, u.data.constData(), size_t(u.data.size()));
|
||||||
} else {
|
} else {
|
||||||
trackedBufferBarrier(cbD, bufD, QGles2Buffer::AccessUpdate);
|
trackedBufferBarrier(cbD, bufD, QGles2Buffer::AccessUpdate);
|
||||||
QGles2CommandBuffer::Command cmd;
|
QGles2CommandBuffer::Command cmd;
|
||||||
@ -1458,7 +1470,7 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
|
|||||||
QGles2CommandBuffer::Command cmd;
|
QGles2CommandBuffer::Command cmd;
|
||||||
cmd.cmd = QGles2CommandBuffer::Command::CopyTex;
|
cmd.cmd = QGles2CommandBuffer::Command::CopyTex;
|
||||||
|
|
||||||
cmd.args.copyTex.srcFaceTarget = srcFaceTargetBase + u.copy.desc.sourceLayer();
|
cmd.args.copyTex.srcFaceTarget = srcFaceTargetBase + uint(u.copy.desc.sourceLayer());
|
||||||
cmd.args.copyTex.srcTexture = srcD->texture;
|
cmd.args.copyTex.srcTexture = srcD->texture;
|
||||||
cmd.args.copyTex.srcLevel = u.copy.desc.sourceLevel();
|
cmd.args.copyTex.srcLevel = u.copy.desc.sourceLevel();
|
||||||
cmd.args.copyTex.srcX = sp.x();
|
cmd.args.copyTex.srcX = sp.x();
|
||||||
@ -1466,7 +1478,7 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
|
|||||||
|
|
||||||
cmd.args.copyTex.dstTarget = dstD->target;
|
cmd.args.copyTex.dstTarget = dstD->target;
|
||||||
cmd.args.copyTex.dstTexture = dstD->texture;
|
cmd.args.copyTex.dstTexture = dstD->texture;
|
||||||
cmd.args.copyTex.dstFaceTarget = dstFaceTargetBase + u.copy.desc.destinationLayer();
|
cmd.args.copyTex.dstFaceTarget = dstFaceTargetBase + uint(u.copy.desc.destinationLayer());
|
||||||
cmd.args.copyTex.dstLevel = u.copy.desc.destinationLevel();
|
cmd.args.copyTex.dstLevel = u.copy.desc.destinationLevel();
|
||||||
cmd.args.copyTex.dstX = dp.x();
|
cmd.args.copyTex.dstX = dp.x();
|
||||||
cmd.args.copyTex.dstY = dp.y();
|
cmd.args.copyTex.dstY = dp.y();
|
||||||
@ -1480,7 +1492,8 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
|
|||||||
cmd.cmd = QGles2CommandBuffer::Command::ReadPixels;
|
cmd.cmd = QGles2CommandBuffer::Command::ReadPixels;
|
||||||
cmd.args.readPixels.result = u.read.result;
|
cmd.args.readPixels.result = u.read.result;
|
||||||
QGles2Texture *texD = QRHI_RES(QGles2Texture, u.read.rb.texture());
|
QGles2Texture *texD = QRHI_RES(QGles2Texture, u.read.rb.texture());
|
||||||
trackedImageBarrier(cbD, texD, QGles2Texture::AccessRead);
|
if (texD)
|
||||||
|
trackedImageBarrier(cbD, texD, QGles2Texture::AccessRead);
|
||||||
cmd.args.readPixels.texture = texD ? texD->texture : 0;
|
cmd.args.readPixels.texture = texD ? texD->texture : 0;
|
||||||
if (texD) {
|
if (texD) {
|
||||||
cmd.args.readPixels.w = texD->m_pixelSize.width();
|
cmd.args.readPixels.w = texD->m_pixelSize.width();
|
||||||
@ -1488,7 +1501,7 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
|
|||||||
cmd.args.readPixels.format = texD->m_format;
|
cmd.args.readPixels.format = texD->m_format;
|
||||||
const GLenum faceTargetBase = texD->m_flags.testFlag(QRhiTexture::CubeMap)
|
const GLenum faceTargetBase = texD->m_flags.testFlag(QRhiTexture::CubeMap)
|
||||||
? GL_TEXTURE_CUBE_MAP_POSITIVE_X : texD->target;
|
? GL_TEXTURE_CUBE_MAP_POSITIVE_X : texD->target;
|
||||||
cmd.args.readPixels.readTarget = faceTargetBase + u.read.rb.layer();
|
cmd.args.readPixels.readTarget = faceTargetBase + uint(u.read.rb.layer());
|
||||||
cmd.args.readPixels.level = u.read.rb.level();
|
cmd.args.readPixels.level = u.read.rb.level();
|
||||||
}
|
}
|
||||||
cbD->commands.append(cmd);
|
cbD->commands.append(cmd);
|
||||||
@ -1848,7 +1861,7 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
|
|||||||
f->glBindVertexArray(0);
|
f->glBindVertexArray(0);
|
||||||
break;
|
break;
|
||||||
case QGles2CommandBuffer::Command::Viewport:
|
case QGles2CommandBuffer::Command::Viewport:
|
||||||
f->glViewport(cmd.args.viewport.x, cmd.args.viewport.y, cmd.args.viewport.w, cmd.args.viewport.h);
|
f->glViewport(GLint(cmd.args.viewport.x), GLint(cmd.args.viewport.y), GLsizei(cmd.args.viewport.w), GLsizei(cmd.args.viewport.h));
|
||||||
f->glDepthRangef(cmd.args.viewport.d0, cmd.args.viewport.d1);
|
f->glDepthRangef(cmd.args.viewport.d0, cmd.args.viewport.d1);
|
||||||
break;
|
break;
|
||||||
case QGles2CommandBuffer::Command::Scissor:
|
case QGles2CommandBuffer::Command::Scissor:
|
||||||
@ -1861,8 +1874,8 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
|
|||||||
{
|
{
|
||||||
QGles2GraphicsPipeline *psD = QRHI_RES(QGles2GraphicsPipeline, cmd.args.stencilRef.ps);
|
QGles2GraphicsPipeline *psD = QRHI_RES(QGles2GraphicsPipeline, cmd.args.stencilRef.ps);
|
||||||
if (psD) {
|
if (psD) {
|
||||||
f->glStencilFuncSeparate(GL_FRONT, toGlCompareOp(psD->m_stencilFront.compareOp), cmd.args.stencilRef.ref, psD->m_stencilReadMask);
|
f->glStencilFuncSeparate(GL_FRONT, toGlCompareOp(psD->m_stencilFront.compareOp), GLint(cmd.args.stencilRef.ref), psD->m_stencilReadMask);
|
||||||
f->glStencilFuncSeparate(GL_BACK, toGlCompareOp(psD->m_stencilBack.compareOp), cmd.args.stencilRef.ref, psD->m_stencilReadMask);
|
f->glStencilFuncSeparate(GL_BACK, toGlCompareOp(psD->m_stencilBack.compareOp), GLint(cmd.args.stencilRef.ref), psD->m_stencilReadMask);
|
||||||
} else {
|
} else {
|
||||||
qWarning("No graphics pipeline active for setStencilRef; ignored");
|
qWarning("No graphics pipeline active for setStencilRef; ignored");
|
||||||
}
|
}
|
||||||
@ -1882,7 +1895,7 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
|
|||||||
// we do not support more than one vertex buffer
|
// we do not support more than one vertex buffer
|
||||||
f->glBindBuffer(GL_ARRAY_BUFFER, cmd.args.bindVertexBuffer.buffer);
|
f->glBindBuffer(GL_ARRAY_BUFFER, cmd.args.bindVertexBuffer.buffer);
|
||||||
|
|
||||||
const int stride = bindings[bindingIdx].stride();
|
const int stride = int(bindings[bindingIdx].stride());
|
||||||
int size = 1;
|
int size = 1;
|
||||||
GLenum type = GL_FLOAT;
|
GLenum type = GL_FLOAT;
|
||||||
bool normalize = false;
|
bool normalize = false;
|
||||||
@ -1924,13 +1937,13 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
|
|||||||
|
|
||||||
const int locationIdx = a.location();
|
const int locationIdx = a.location();
|
||||||
quint32 ofs = a.offset() + cmd.args.bindVertexBuffer.offset;
|
quint32 ofs = a.offset() + cmd.args.bindVertexBuffer.offset;
|
||||||
f->glVertexAttribPointer(locationIdx, size, type, normalize, stride,
|
f->glVertexAttribPointer(GLuint(locationIdx), size, type, normalize, stride,
|
||||||
reinterpret_cast<const GLvoid *>(quintptr(ofs)));
|
reinterpret_cast<const GLvoid *>(quintptr(ofs)));
|
||||||
f->glEnableVertexAttribArray(locationIdx);
|
f->glEnableVertexAttribArray(GLuint(locationIdx));
|
||||||
if (bindings[bindingIdx].classification() == QRhiVertexInputBinding::PerInstance
|
if (bindings[bindingIdx].classification() == QRhiVertexInputBinding::PerInstance
|
||||||
&& caps.instancing)
|
&& caps.instancing)
|
||||||
{
|
{
|
||||||
f->glVertexAttribDivisor(locationIdx, bindings[bindingIdx].instanceStepRate());
|
f->glVertexAttribDivisor(GLuint(locationIdx), GLuint(bindings[bindingIdx].instanceStepRate()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1949,10 +1962,10 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
|
|||||||
QGles2GraphicsPipeline *psD = QRHI_RES(QGles2GraphicsPipeline, cmd.args.draw.ps);
|
QGles2GraphicsPipeline *psD = QRHI_RES(QGles2GraphicsPipeline, cmd.args.draw.ps);
|
||||||
if (psD) {
|
if (psD) {
|
||||||
if (cmd.args.draw.instanceCount == 1 || !caps.instancing) {
|
if (cmd.args.draw.instanceCount == 1 || !caps.instancing) {
|
||||||
f->glDrawArrays(psD->drawMode, cmd.args.draw.firstVertex, cmd.args.draw.vertexCount);
|
f->glDrawArrays(psD->drawMode, GLint(cmd.args.draw.firstVertex), GLsizei(cmd.args.draw.vertexCount));
|
||||||
} else {
|
} else {
|
||||||
f->glDrawArraysInstanced(psD->drawMode, cmd.args.draw.firstVertex, cmd.args.draw.vertexCount,
|
f->glDrawArraysInstanced(psD->drawMode, GLint(cmd.args.draw.firstVertex), GLsizei(cmd.args.draw.vertexCount),
|
||||||
cmd.args.draw.instanceCount);
|
GLsizei(cmd.args.draw.instanceCount));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
qWarning("No graphics pipeline active for draw; ignored");
|
qWarning("No graphics pipeline active for draw; ignored");
|
||||||
@ -1968,30 +1981,30 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
|
|||||||
if (cmd.args.drawIndexed.instanceCount == 1 || !caps.instancing) {
|
if (cmd.args.drawIndexed.instanceCount == 1 || !caps.instancing) {
|
||||||
if (cmd.args.drawIndexed.baseVertex != 0 && caps.baseVertex) {
|
if (cmd.args.drawIndexed.baseVertex != 0 && caps.baseVertex) {
|
||||||
f->glDrawElementsBaseVertex(psD->drawMode,
|
f->glDrawElementsBaseVertex(psD->drawMode,
|
||||||
cmd.args.drawIndexed.indexCount,
|
GLsizei(cmd.args.drawIndexed.indexCount),
|
||||||
indexType,
|
indexType,
|
||||||
ofs,
|
ofs,
|
||||||
cmd.args.drawIndexed.baseVertex);
|
cmd.args.drawIndexed.baseVertex);
|
||||||
} else {
|
} else {
|
||||||
f->glDrawElements(psD->drawMode,
|
f->glDrawElements(psD->drawMode,
|
||||||
cmd.args.drawIndexed.indexCount,
|
GLsizei(cmd.args.drawIndexed.indexCount),
|
||||||
indexType,
|
indexType,
|
||||||
ofs);
|
ofs);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (cmd.args.drawIndexed.baseVertex != 0 && caps.baseVertex) {
|
if (cmd.args.drawIndexed.baseVertex != 0 && caps.baseVertex) {
|
||||||
f->glDrawElementsInstancedBaseVertex(psD->drawMode,
|
f->glDrawElementsInstancedBaseVertex(psD->drawMode,
|
||||||
cmd.args.drawIndexed.indexCount,
|
GLsizei(cmd.args.drawIndexed.indexCount),
|
||||||
indexType,
|
indexType,
|
||||||
ofs,
|
ofs,
|
||||||
cmd.args.drawIndexed.instanceCount,
|
GLsizei(cmd.args.drawIndexed.instanceCount),
|
||||||
cmd.args.drawIndexed.baseVertex);
|
cmd.args.drawIndexed.baseVertex);
|
||||||
} else {
|
} else {
|
||||||
f->glDrawElementsInstanced(psD->drawMode,
|
f->glDrawElementsInstanced(psD->drawMode,
|
||||||
cmd.args.drawIndexed.indexCount,
|
GLsizei(cmd.args.drawIndexed.indexCount),
|
||||||
indexType,
|
indexType,
|
||||||
ofs,
|
ofs,
|
||||||
cmd.args.drawIndexed.instanceCount);
|
GLsizei(cmd.args.drawIndexed.instanceCount));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -2016,7 +2029,7 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
|
|||||||
const int colorAttCount = cmd.args.bindFramebuffer.colorAttCount;
|
const int colorAttCount = cmd.args.bindFramebuffer.colorAttCount;
|
||||||
QVarLengthArray<GLenum, 8> bufs;
|
QVarLengthArray<GLenum, 8> bufs;
|
||||||
for (int i = 0; i < colorAttCount; ++i)
|
for (int i = 0; i < colorAttCount; ++i)
|
||||||
bufs.append(GL_COLOR_ATTACHMENT0 + i);
|
bufs.append(GL_COLOR_ATTACHMENT0 + uint(i));
|
||||||
f->glDrawBuffers(colorAttCount, bufs.constData());
|
f->glDrawBuffers(colorAttCount, bufs.constData());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -2044,7 +2057,7 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
|
|||||||
f->glClearDepthf(cmd.args.clear.d);
|
f->glClearDepthf(cmd.args.clear.d);
|
||||||
}
|
}
|
||||||
if (cmd.args.clear.mask & GL_STENCIL_BUFFER_BIT)
|
if (cmd.args.clear.mask & GL_STENCIL_BUFFER_BIT)
|
||||||
f->glClearStencil(cmd.args.clear.s);
|
f->glClearStencil(GLint(cmd.args.clear.s));
|
||||||
f->glClear(cmd.args.clear.mask);
|
f->glClear(cmd.args.clear.mask);
|
||||||
break;
|
break;
|
||||||
case QGles2CommandBuffer::Command::BufferSubData:
|
case QGles2CommandBuffer::Command::BufferSubData:
|
||||||
@ -2288,7 +2301,7 @@ void QRhiGles2::bindShaderResources(QRhiGraphicsPipeline *maybeGraphicsPs, QRhiC
|
|||||||
if (dynOfsCount) {
|
if (dynOfsCount) {
|
||||||
for (int j = 0; j < dynOfsCount; ++j) {
|
for (int j = 0; j < dynOfsCount; ++j) {
|
||||||
if (dynOfsPairs[2 * j] == uint(b->binding)) {
|
if (dynOfsPairs[2 * j] == uint(b->binding)) {
|
||||||
viewOffset = dynOfsPairs[2 * j + 1];
|
viewOffset = int(dynOfsPairs[2 * j + 1]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2379,20 +2392,20 @@ void QRhiGles2::bindShaderResources(QRhiGraphicsPipeline *maybeGraphicsPs, QRhiC
|
|||||||
|
|
||||||
for (QGles2SamplerDescription &sampler : samplers) {
|
for (QGles2SamplerDescription &sampler : samplers) {
|
||||||
if (sampler.binding == b->binding) {
|
if (sampler.binding == b->binding) {
|
||||||
f->glActiveTexture(GL_TEXTURE0 + texUnit);
|
f->glActiveTexture(GL_TEXTURE0 + uint(texUnit));
|
||||||
f->glBindTexture(texD->target, texD->texture);
|
f->glBindTexture(texD->target, texD->texture);
|
||||||
|
|
||||||
if (texD->samplerState != samplerD->d) {
|
if (texD->samplerState != samplerD->d) {
|
||||||
f->glTexParameteri(texD->target, GL_TEXTURE_MIN_FILTER, samplerD->d.glminfilter);
|
f->glTexParameteri(texD->target, GL_TEXTURE_MIN_FILTER, GLint(samplerD->d.glminfilter));
|
||||||
f->glTexParameteri(texD->target, GL_TEXTURE_MAG_FILTER, samplerD->d.glmagfilter);
|
f->glTexParameteri(texD->target, GL_TEXTURE_MAG_FILTER, GLint(samplerD->d.glmagfilter));
|
||||||
f->glTexParameteri(texD->target, GL_TEXTURE_WRAP_S, samplerD->d.glwraps);
|
f->glTexParameteri(texD->target, GL_TEXTURE_WRAP_S, GLint(samplerD->d.glwraps));
|
||||||
f->glTexParameteri(texD->target, GL_TEXTURE_WRAP_T, samplerD->d.glwrapt);
|
f->glTexParameteri(texD->target, GL_TEXTURE_WRAP_T, GLint(samplerD->d.glwrapt));
|
||||||
// 3D textures not supported by GLES 2.0 or by us atm...
|
// 3D textures not supported by GLES 2.0 or by us atm...
|
||||||
//f->glTexParameteri(texD->target, GL_TEXTURE_WRAP_R, samplerD->d.glwrapr);
|
//f->glTexParameteri(texD->target, GL_TEXTURE_WRAP_R, samplerD->d.glwrapr);
|
||||||
if (caps.textureCompareMode) {
|
if (caps.textureCompareMode) {
|
||||||
if (samplerD->d.gltexcomparefunc != GL_NEVER) {
|
if (samplerD->d.gltexcomparefunc != GL_NEVER) {
|
||||||
f->glTexParameteri(texD->target, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
|
f->glTexParameteri(texD->target, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
|
||||||
f->glTexParameteri(texD->target, GL_TEXTURE_COMPARE_FUNC, samplerD->d.gltexcomparefunc);
|
f->glTexParameteri(texD->target, GL_TEXTURE_COMPARE_FUNC, GLint(samplerD->d.gltexcomparefunc));
|
||||||
} else {
|
} else {
|
||||||
f->glTexParameteri(texD->target, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
f->glTexParameteri(texD->target, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
||||||
}
|
}
|
||||||
@ -2419,7 +2432,7 @@ void QRhiGles2::bindShaderResources(QRhiGraphicsPipeline *maybeGraphicsPs, QRhiC
|
|||||||
access = GL_READ_ONLY;
|
access = GL_READ_ONLY;
|
||||||
else if (b->type == QRhiShaderResourceBinding::ImageStore)
|
else if (b->type == QRhiShaderResourceBinding::ImageStore)
|
||||||
access = GL_WRITE_ONLY;
|
access = GL_WRITE_ONLY;
|
||||||
f->glBindImageTexture(b->binding, texD->texture,
|
f->glBindImageTexture(GLuint(b->binding), texD->texture,
|
||||||
b->u.simage.level, layered, 0,
|
b->u.simage.level, layered, 0,
|
||||||
access, texD->glsizedintformat);
|
access, texD->glsizedintformat);
|
||||||
}
|
}
|
||||||
@ -2432,9 +2445,9 @@ void QRhiGles2::bindShaderResources(QRhiGraphicsPipeline *maybeGraphicsPs, QRhiC
|
|||||||
{
|
{
|
||||||
QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, b->u.sbuf.buf);
|
QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, b->u.sbuf.buf);
|
||||||
if (b->u.sbuf.offset == 0 && b->u.sbuf.maybeSize == 0)
|
if (b->u.sbuf.offset == 0 && b->u.sbuf.maybeSize == 0)
|
||||||
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, b->binding, bufD->buffer);
|
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, GLuint(b->binding), bufD->buffer);
|
||||||
else
|
else
|
||||||
f->glBindBufferRange(GL_SHADER_STORAGE_BUFFER, b->binding, bufD->buffer,
|
f->glBindBufferRange(GL_SHADER_STORAGE_BUFFER, GLuint(b->binding), bufD->buffer,
|
||||||
b->u.sbuf.offset, b->u.sbuf.maybeSize ? b->u.sbuf.maybeSize : bufD->m_size);
|
b->u.sbuf.offset, b->u.sbuf.maybeSize ? b->u.sbuf.maybeSize : bufD->m_size);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2556,10 +2569,10 @@ void QRhiGles2::beginPass(QRhiCommandBuffer *cb,
|
|||||||
clearCmd.args.clear.mask |= GL_COLOR_BUFFER_BIT;
|
clearCmd.args.clear.mask |= GL_COLOR_BUFFER_BIT;
|
||||||
if (rtD->dsAttCount && wantsDsClear)
|
if (rtD->dsAttCount && wantsDsClear)
|
||||||
clearCmd.args.clear.mask |= GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
|
clearCmd.args.clear.mask |= GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
|
||||||
clearCmd.args.clear.c[0] = colorClearValue.redF();
|
clearCmd.args.clear.c[0] = float(colorClearValue.redF());
|
||||||
clearCmd.args.clear.c[1] = colorClearValue.greenF();
|
clearCmd.args.clear.c[1] = float(colorClearValue.greenF());
|
||||||
clearCmd.args.clear.c[2] = colorClearValue.blueF();
|
clearCmd.args.clear.c[2] = float(colorClearValue.blueF());
|
||||||
clearCmd.args.clear.c[3] = colorClearValue.alphaF();
|
clearCmd.args.clear.c[3] = float(colorClearValue.alphaF());
|
||||||
clearCmd.args.clear.d = depthStencilClearValue.depthClearValue();
|
clearCmd.args.clear.d = depthStencilClearValue.depthClearValue();
|
||||||
clearCmd.args.clear.s = depthStencilClearValue.stencilClearValue();
|
clearCmd.args.clear.s = depthStencilClearValue.stencilClearValue();
|
||||||
cbD->commands.append(clearCmd);
|
cbD->commands.append(clearCmd);
|
||||||
@ -2597,7 +2610,7 @@ void QRhiGles2::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resource
|
|||||||
QGles2Texture *colorTexD = QRHI_RES(QGles2Texture, colorAtt.resolveTexture());
|
QGles2Texture *colorTexD = QRHI_RES(QGles2Texture, colorAtt.resolveTexture());
|
||||||
const GLenum faceTargetBase = colorTexD->m_flags.testFlag(QRhiTexture::CubeMap) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X
|
const GLenum faceTargetBase = colorTexD->m_flags.testFlag(QRhiTexture::CubeMap) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X
|
||||||
: colorTexD->target;
|
: colorTexD->target;
|
||||||
cmd.args.blitFromRb.target = faceTargetBase + colorAtt.resolveLayer();
|
cmd.args.blitFromRb.target = faceTargetBase + uint(colorAtt.resolveLayer());
|
||||||
cmd.args.blitFromRb.texture = colorTexD->texture;
|
cmd.args.blitFromRb.texture = colorTexD->texture;
|
||||||
cmd.args.blitFromRb.dstLevel = colorAtt.resolveLevel();
|
cmd.args.blitFromRb.dstLevel = colorAtt.resolveLevel();
|
||||||
cbD->commands.append(cmd);
|
cbD->commands.append(cmd);
|
||||||
@ -2664,9 +2677,9 @@ void QRhiGles2::dispatch(QRhiCommandBuffer *cb, int x, int y, int z)
|
|||||||
|
|
||||||
QGles2CommandBuffer::Command cmd;
|
QGles2CommandBuffer::Command cmd;
|
||||||
cmd.cmd = QGles2CommandBuffer::Command::Dispatch;
|
cmd.cmd = QGles2CommandBuffer::Command::Dispatch;
|
||||||
cmd.args.dispatch.x = x;
|
cmd.args.dispatch.x = GLuint(x);
|
||||||
cmd.args.dispatch.y = y;
|
cmd.args.dispatch.y = GLuint(y);
|
||||||
cmd.args.dispatch.z = z;
|
cmd.args.dispatch.z = GLuint(z);
|
||||||
cbD->commands.append(cmd);
|
cbD->commands.append(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2818,7 +2831,7 @@ void QRhiGles2::gatherUniforms(GLuint program, const QShaderDescription::Uniform
|
|||||||
uniform.glslLocation = f->glGetUniformLocation(program, name.constData());
|
uniform.glslLocation = f->glGetUniformLocation(program, name.constData());
|
||||||
if (uniform.glslLocation >= 0) {
|
if (uniform.glslLocation >= 0) {
|
||||||
uniform.binding = ub.binding;
|
uniform.binding = ub.binding;
|
||||||
uniform.offset = blockMember.offset;
|
uniform.offset = uint(blockMember.offset);
|
||||||
uniform.size = blockMember.size;
|
uniform.size = blockMember.size;
|
||||||
dst->append(uniform);
|
dst->append(uniform);
|
||||||
}
|
}
|
||||||
@ -2882,7 +2895,7 @@ bool QGles2Buffer::build()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ubuf.resize(nonZeroSize);
|
ubuf.resize(nonZeroSize);
|
||||||
QRHI_PROF_F(newBuffer(this, nonZeroSize, 0, 1));
|
QRHI_PROF_F(newBuffer(this, uint(nonZeroSize), 0, 1));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2901,7 +2914,7 @@ bool QGles2Buffer::build()
|
|||||||
|
|
||||||
usageState.access = AccessNone;
|
usageState.access = AccessNone;
|
||||||
|
|
||||||
QRHI_PROF_F(newBuffer(this, nonZeroSize, 1, 0));
|
QRHI_PROF_F(newBuffer(this, uint(nonZeroSize), 1, 0));
|
||||||
rhiD->registerResource(this);
|
rhiD->registerResource(this);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -3172,13 +3185,13 @@ bool QGles2Texture::build()
|
|||||||
for (int layer = 0, layerCount = isCube ? 6 : 1; layer != layerCount; ++layer) {
|
for (int layer = 0, layerCount = isCube ? 6 : 1; layer != layerCount; ++layer) {
|
||||||
for (int level = 0; level != mipLevelCount; ++level) {
|
for (int level = 0; level != mipLevelCount; ++level) {
|
||||||
const QSize mipSize = rhiD->q->sizeForMipLevel(level, size);
|
const QSize mipSize = rhiD->q->sizeForMipLevel(level, size);
|
||||||
rhiD->f->glTexImage2D(faceTargetBase + layer, level, glintformat,
|
rhiD->f->glTexImage2D(faceTargetBase + uint(layer), level, GLint(glintformat),
|
||||||
mipSize.width(), mipSize.height(), 0,
|
mipSize.width(), mipSize.height(), 0,
|
||||||
glformat, gltype, nullptr);
|
glformat, gltype, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rhiD->f->glTexImage2D(target, 0, glintformat, size.width(), size.height(),
|
rhiD->f->glTexImage2D(target, 0, GLint(glintformat), size.width(), size.height(),
|
||||||
0, glformat, gltype, nullptr);
|
0, glformat, gltype, nullptr);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -3381,14 +3394,15 @@ bool QGles2TextureRenderTarget::build()
|
|||||||
QGles2Texture *texD = QRHI_RES(QGles2Texture, texture);
|
QGles2Texture *texD = QRHI_RES(QGles2Texture, texture);
|
||||||
Q_ASSERT(texD->texture && texD->specified);
|
Q_ASSERT(texD->texture && texD->specified);
|
||||||
const GLenum faceTargetBase = texD->flags().testFlag(QRhiTexture::CubeMap) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : texD->target;
|
const GLenum faceTargetBase = texD->flags().testFlag(QRhiTexture::CubeMap) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : texD->target;
|
||||||
rhiD->f->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, faceTargetBase + colorAtt.layer(), texD->texture, colorAtt.level());
|
rhiD->f->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + uint(i), faceTargetBase + uint(colorAtt.layer()),
|
||||||
|
texD->texture, colorAtt.level());
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
d.pixelSize = texD->pixelSize();
|
d.pixelSize = texD->pixelSize();
|
||||||
d.sampleCount = 1;
|
d.sampleCount = 1;
|
||||||
}
|
}
|
||||||
} else if (renderBuffer) {
|
} else if (renderBuffer) {
|
||||||
QGles2RenderBuffer *rbD = QRHI_RES(QGles2RenderBuffer, renderBuffer);
|
QGles2RenderBuffer *rbD = QRHI_RES(QGles2RenderBuffer, renderBuffer);
|
||||||
rhiD->f->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_RENDERBUFFER, rbD->renderbuffer);
|
rhiD->f->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + uint(i), GL_RENDERBUFFER, rbD->renderbuffer);
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
d.pixelSize = rbD->pixelSize();
|
d.pixelSize = rbD->pixelSize();
|
||||||
d.sampleCount = rbD->samples;
|
d.sampleCount = rbD->samples;
|
||||||
@ -3538,7 +3552,7 @@ bool QGles2GraphicsPipeline::build()
|
|||||||
|
|
||||||
for (auto inVar : vsDesc.inputVariables()) {
|
for (auto inVar : vsDesc.inputVariables()) {
|
||||||
const QByteArray name = inVar.name.toUtf8();
|
const QByteArray name = inVar.name.toUtf8();
|
||||||
rhiD->f->glBindAttribLocation(program, inVar.location, name.constData());
|
rhiD->f->glBindAttribLocation(program, GLuint(inVar.location), name.constData());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rhiD->linkProgram(program))
|
if (!rhiD->linkProgram(program))
|
||||||
@ -3684,7 +3698,7 @@ bool QGles2SwapChain::buildOrResize()
|
|||||||
|
|
||||||
rt.d.rp = QRHI_RES(QGles2RenderPassDescriptor, m_renderPassDesc);
|
rt.d.rp = QRHI_RES(QGles2RenderPassDescriptor, m_renderPassDesc);
|
||||||
rt.d.pixelSize = pixelSize;
|
rt.d.pixelSize = pixelSize;
|
||||||
rt.d.dpr = m_window->devicePixelRatio();
|
rt.d.dpr = float(m_window->devicePixelRatio());
|
||||||
rt.d.sampleCount = qBound(1, m_sampleCount, 64);
|
rt.d.sampleCount = qBound(1, m_sampleCount, 64);
|
||||||
rt.d.colorAttCount = 1;
|
rt.d.colorAttCount = 1;
|
||||||
rt.d.dsAttCount = m_depthStencil ? 1 : 0;
|
rt.d.dsAttCount = m_depthStencil ? 1 : 0;
|
||||||
|
@ -664,8 +664,9 @@ public:
|
|||||||
int resourceLimit(QRhi::ResourceLimit limit) const override;
|
int resourceLimit(QRhi::ResourceLimit limit) const override;
|
||||||
const QRhiNativeHandles *nativeHandles() override;
|
const QRhiNativeHandles *nativeHandles() override;
|
||||||
void sendVMemStatsToProfiler() override;
|
void sendVMemStatsToProfiler() override;
|
||||||
void makeThreadLocalNativeContextCurrent() override;
|
bool makeThreadLocalNativeContextCurrent() override;
|
||||||
void releaseCachedResources() override;
|
void releaseCachedResources() override;
|
||||||
|
bool isDeviceLost() const override;
|
||||||
|
|
||||||
bool ensureContext(QSurface *surface = nullptr) const;
|
bool ensureContext(QSurface *surface = nullptr) const;
|
||||||
void executeDeferredReleases();
|
void executeDeferredReleases();
|
||||||
@ -769,6 +770,7 @@ public:
|
|||||||
QVector<GLint> supportedCompressedFormats;
|
QVector<GLint> supportedCompressedFormats;
|
||||||
mutable QVector<int> supportedSampleCountList;
|
mutable QVector<int> supportedSampleCountList;
|
||||||
QRhiGles2NativeHandles nativeHandlesStruct;
|
QRhiGles2NativeHandles nativeHandlesStruct;
|
||||||
|
mutable bool contextLost = false;
|
||||||
|
|
||||||
struct DeferredReleaseEntry {
|
struct DeferredReleaseEntry {
|
||||||
enum Type {
|
enum Type {
|
||||||
|
@ -352,7 +352,8 @@ QRhiMetal::~QRhiMetal()
|
|||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint aligned(uint v, uint byteAlign)
|
template <class Int>
|
||||||
|
inline Int aligned(Int v, Int byteAlign)
|
||||||
{
|
{
|
||||||
return (v + byteAlign - 1) & ~(byteAlign - 1);
|
return (v + byteAlign - 1) & ~(byteAlign - 1);
|
||||||
}
|
}
|
||||||
@ -582,9 +583,10 @@ void QRhiMetal::sendVMemStatsToProfiler()
|
|||||||
// nothing to do here
|
// nothing to do here
|
||||||
}
|
}
|
||||||
|
|
||||||
void QRhiMetal::makeThreadLocalNativeContextCurrent()
|
bool QRhiMetal::makeThreadLocalNativeContextCurrent()
|
||||||
{
|
{
|
||||||
// nothing to do here
|
// not applicable
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QRhiMetal::releaseCachedResources()
|
void QRhiMetal::releaseCachedResources()
|
||||||
@ -595,6 +597,11 @@ void QRhiMetal::releaseCachedResources()
|
|||||||
d->shaderCache.clear();
|
d->shaderCache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QRhiMetal::isDeviceLost() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
QRhiRenderBuffer *QRhiMetal::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
|
QRhiRenderBuffer *QRhiMetal::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
|
||||||
int sampleCount, QRhiRenderBuffer::Flags flags)
|
int sampleCount, QRhiRenderBuffer::Flags flags)
|
||||||
{
|
{
|
||||||
@ -655,7 +662,7 @@ void QRhiMetal::enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD
|
|||||||
{
|
{
|
||||||
QMetalBuffer *bufD = QRHI_RES(QMetalBuffer, b->u.ubuf.buf);
|
QMetalBuffer *bufD = QRHI_RES(QMetalBuffer, b->u.ubuf.buf);
|
||||||
id<MTLBuffer> mtlbuf = bufD->d->buf[bufD->d->slotted ? currentFrameSlot : 0];
|
id<MTLBuffer> mtlbuf = bufD->d->buf[bufD->d->slotted ? currentFrameSlot : 0];
|
||||||
uint offset = b->u.ubuf.offset;
|
uint offset = uint(b->u.ubuf.offset);
|
||||||
for (int i = 0; i < dynamicOffsetCount; ++i) {
|
for (int i = 0; i < dynamicOffsetCount; ++i) {
|
||||||
const QRhiCommandBuffer::DynamicOffset &dynOfs(dynamicOffsets[i]);
|
const QRhiCommandBuffer::DynamicOffset &dynOfs(dynamicOffsets[i]);
|
||||||
if (dynOfs.first == b->binding) {
|
if (dynOfs.first == b->binding) {
|
||||||
@ -719,7 +726,7 @@ void QRhiMetal::enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD
|
|||||||
{
|
{
|
||||||
QMetalBuffer *bufD = QRHI_RES(QMetalBuffer, b->u.sbuf.buf);
|
QMetalBuffer *bufD = QRHI_RES(QMetalBuffer, b->u.sbuf.buf);
|
||||||
id<MTLBuffer> mtlbuf = bufD->d->buf[0];
|
id<MTLBuffer> mtlbuf = bufD->d->buf[0];
|
||||||
uint offset = b->u.sbuf.offset;
|
uint offset = uint(b->u.sbuf.offset);
|
||||||
if (b->stage.testFlag(QRhiShaderResourceBinding::VertexStage)) {
|
if (b->stage.testFlag(QRhiShaderResourceBinding::VertexStage)) {
|
||||||
res[0].buffers.feed(b->binding, mtlbuf);
|
res[0].buffers.feed(b->binding, mtlbuf);
|
||||||
res[0].bufferOffsets.feed(b->binding, offset);
|
res[0].bufferOffsets.feed(b->binding, offset);
|
||||||
@ -751,17 +758,17 @@ void QRhiMetal::enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD
|
|||||||
case 0:
|
case 0:
|
||||||
[cbD->d->currentRenderPassEncoder setVertexBuffers: bufferBatch.resources.constData()
|
[cbD->d->currentRenderPassEncoder setVertexBuffers: bufferBatch.resources.constData()
|
||||||
offsets: offsetBatch.resources.constData()
|
offsets: offsetBatch.resources.constData()
|
||||||
withRange: NSMakeRange(bufferBatch.startBinding, bufferBatch.resources.count())];
|
withRange: NSMakeRange(bufferBatch.startBinding, NSUInteger(bufferBatch.resources.count()))];
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
[cbD->d->currentRenderPassEncoder setFragmentBuffers: bufferBatch.resources.constData()
|
[cbD->d->currentRenderPassEncoder setFragmentBuffers: bufferBatch.resources.constData()
|
||||||
offsets: offsetBatch.resources.constData()
|
offsets: offsetBatch.resources.constData()
|
||||||
withRange: NSMakeRange(bufferBatch.startBinding, bufferBatch.resources.count())];
|
withRange: NSMakeRange(bufferBatch.startBinding, NSUInteger(bufferBatch.resources.count()))];
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
[cbD->d->currentComputePassEncoder setBuffers: bufferBatch.resources.constData()
|
[cbD->d->currentComputePassEncoder setBuffers: bufferBatch.resources.constData()
|
||||||
offsets: offsetBatch.resources.constData()
|
offsets: offsetBatch.resources.constData()
|
||||||
withRange: NSMakeRange(bufferBatch.startBinding, bufferBatch.resources.count())];
|
withRange: NSMakeRange(bufferBatch.startBinding, NSUInteger(bufferBatch.resources.count()))];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Q_UNREACHABLE();
|
Q_UNREACHABLE();
|
||||||
@ -780,15 +787,15 @@ void QRhiMetal::enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD
|
|||||||
switch (idx) {
|
switch (idx) {
|
||||||
case 0:
|
case 0:
|
||||||
[cbD->d->currentRenderPassEncoder setVertexTextures: batch.resources.constData()
|
[cbD->d->currentRenderPassEncoder setVertexTextures: batch.resources.constData()
|
||||||
withRange: NSMakeRange(batch.startBinding, batch.resources.count())];
|
withRange: NSMakeRange(batch.startBinding, NSUInteger(batch.resources.count()))];
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
[cbD->d->currentRenderPassEncoder setFragmentTextures: batch.resources.constData()
|
[cbD->d->currentRenderPassEncoder setFragmentTextures: batch.resources.constData()
|
||||||
withRange: NSMakeRange(batch.startBinding, batch.resources.count())];
|
withRange: NSMakeRange(batch.startBinding, NSUInteger(batch.resources.count()))];
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
[cbD->d->currentComputePassEncoder setTextures: batch.resources.constData()
|
[cbD->d->currentComputePassEncoder setTextures: batch.resources.constData()
|
||||||
withRange: NSMakeRange(batch.startBinding, batch.resources.count())];
|
withRange: NSMakeRange(batch.startBinding, NSUInteger(batch.resources.count()))];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Q_UNREACHABLE();
|
Q_UNREACHABLE();
|
||||||
@ -800,15 +807,15 @@ void QRhiMetal::enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD
|
|||||||
switch (idx) {
|
switch (idx) {
|
||||||
case 0:
|
case 0:
|
||||||
[cbD->d->currentRenderPassEncoder setVertexSamplerStates: batch.resources.constData()
|
[cbD->d->currentRenderPassEncoder setVertexSamplerStates: batch.resources.constData()
|
||||||
withRange: NSMakeRange(batch.startBinding, batch.resources.count())];
|
withRange: NSMakeRange(batch.startBinding, NSUInteger(batch.resources.count()))];
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
[cbD->d->currentRenderPassEncoder setFragmentSamplerStates: batch.resources.constData()
|
[cbD->d->currentRenderPassEncoder setFragmentSamplerStates: batch.resources.constData()
|
||||||
withRange: NSMakeRange(batch.startBinding, batch.resources.count())];
|
withRange: NSMakeRange(batch.startBinding, NSUInteger(batch.resources.count()))];
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
[cbD->d->currentComputePassEncoder setSamplerStates: batch.resources.constData()
|
[cbD->d->currentComputePassEncoder setSamplerStates: batch.resources.constData()
|
||||||
withRange: NSMakeRange(batch.startBinding, batch.resources.count())];
|
withRange: NSMakeRange(batch.startBinding, NSUInteger(batch.resources.count()))];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Q_UNREACHABLE();
|
Q_UNREACHABLE();
|
||||||
@ -1006,7 +1013,7 @@ void QRhiMetal::setVertexInput(QRhiCommandBuffer *cb,
|
|||||||
[cbD->d->currentRenderPassEncoder setVertexBuffers:
|
[cbD->d->currentRenderPassEncoder setVertexBuffers:
|
||||||
bufferBatch.resources.constData()
|
bufferBatch.resources.constData()
|
||||||
offsets: offsetBatch.resources.constData()
|
offsets: offsetBatch.resources.constData()
|
||||||
withRange: NSMakeRange(firstVertexBinding + bufferBatch.startBinding, bufferBatch.resources.count())];
|
withRange: NSMakeRange(uint(firstVertexBinding) + bufferBatch.startBinding, NSUInteger(bufferBatch.resources.count()))];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1067,21 +1074,21 @@ void QRhiMetal::setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
MTLViewport vp;
|
MTLViewport vp;
|
||||||
vp.originX = x;
|
vp.originX = double(x);
|
||||||
vp.originY = y;
|
vp.originY = double(y);
|
||||||
vp.width = w;
|
vp.width = double(w);
|
||||||
vp.height = h;
|
vp.height = double(h);
|
||||||
vp.znear = viewport.minDepth();
|
vp.znear = double(viewport.minDepth());
|
||||||
vp.zfar = viewport.maxDepth();
|
vp.zfar = double(viewport.maxDepth());
|
||||||
|
|
||||||
[cbD->d->currentRenderPassEncoder setViewport: vp];
|
[cbD->d->currentRenderPassEncoder setViewport: vp];
|
||||||
|
|
||||||
if (!QRHI_RES(QMetalGraphicsPipeline, cbD->currentGraphicsPipeline)->m_flags.testFlag(QRhiGraphicsPipeline::UsesScissor)) {
|
if (!QRHI_RES(QMetalGraphicsPipeline, cbD->currentGraphicsPipeline)->m_flags.testFlag(QRhiGraphicsPipeline::UsesScissor)) {
|
||||||
MTLScissorRect s;
|
MTLScissorRect s;
|
||||||
s.x = x;
|
s.x = NSUInteger(x);
|
||||||
s.y = y;
|
s.y = NSUInteger(y);
|
||||||
s.width = w;
|
s.width = NSUInteger(w);
|
||||||
s.height = h;
|
s.height = NSUInteger(h);
|
||||||
[cbD->d->currentRenderPassEncoder setScissorRect: s];
|
[cbD->d->currentRenderPassEncoder setScissorRect: s];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1099,10 +1106,10 @@ void QRhiMetal::setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
MTLScissorRect s;
|
MTLScissorRect s;
|
||||||
s.x = x;
|
s.x = NSUInteger(x);
|
||||||
s.y = y;
|
s.y = NSUInteger(y);
|
||||||
s.width = w;
|
s.width = NSUInteger(w);
|
||||||
s.height = h;
|
s.height = NSUInteger(h);
|
||||||
|
|
||||||
[cbD->d->currentRenderPassEncoder setScissorRect: s];
|
[cbD->d->currentRenderPassEncoder setScissorRect: s];
|
||||||
}
|
}
|
||||||
@ -1112,7 +1119,8 @@ void QRhiMetal::setBlendConstants(QRhiCommandBuffer *cb, const QColor &c)
|
|||||||
QMetalCommandBuffer *cbD = QRHI_RES(QMetalCommandBuffer, cb);
|
QMetalCommandBuffer *cbD = QRHI_RES(QMetalCommandBuffer, cb);
|
||||||
Q_ASSERT(cbD->recordingPass == QMetalCommandBuffer::RenderPass);
|
Q_ASSERT(cbD->recordingPass == QMetalCommandBuffer::RenderPass);
|
||||||
|
|
||||||
[cbD->d->currentRenderPassEncoder setBlendColorRed: c.redF() green: c.greenF() blue: c.blueF() alpha: c.alphaF()];
|
[cbD->d->currentRenderPassEncoder setBlendColorRed: float(c.redF())
|
||||||
|
green: float(c.greenF()) blue: float(c.blueF()) alpha: float(c.alphaF())];
|
||||||
}
|
}
|
||||||
|
|
||||||
void QRhiMetal::setStencilRef(QRhiCommandBuffer *cb, quint32 refValue)
|
void QRhiMetal::setStencilRef(QRhiCommandBuffer *cb, quint32 refValue)
|
||||||
@ -1144,7 +1152,7 @@ void QRhiMetal::drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
const quint32 indexOffset = cbD->currentIndexOffset + firstIndex * (cbD->currentIndexFormat == QRhiCommandBuffer::IndexUInt16 ? 2 : 4);
|
const quint32 indexOffset = cbD->currentIndexOffset + firstIndex * (cbD->currentIndexFormat == QRhiCommandBuffer::IndexUInt16 ? 2 : 4);
|
||||||
Q_ASSERT(indexOffset == aligned(indexOffset, 4));
|
Q_ASSERT(indexOffset == aligned<quint32>(indexOffset, 4));
|
||||||
|
|
||||||
QMetalBuffer *ibufD = QRHI_RES(QMetalBuffer, cbD->currentIndexBuffer);
|
QMetalBuffer *ibufD = QRHI_RES(QMetalBuffer, cbD->currentIndexBuffer);
|
||||||
id<MTLBuffer> mtlbuf = ibufD->d->buf[ibufD->d->slotted ? currentFrameSlot : 0];
|
id<MTLBuffer> mtlbuf = ibufD->d->buf[ibufD->d->slotted ? currentFrameSlot : 0];
|
||||||
@ -1402,7 +1410,7 @@ MTLRenderPassDescriptor *QRhiMetalData::createDefaultRenderPass(bool hasDepthSte
|
|||||||
MTLClearColor c = MTLClearColorMake(colorClearValue.redF(), colorClearValue.greenF(), colorClearValue.blueF(),
|
MTLClearColor c = MTLClearColorMake(colorClearValue.redF(), colorClearValue.greenF(), colorClearValue.blueF(),
|
||||||
colorClearValue.alphaF());
|
colorClearValue.alphaF());
|
||||||
|
|
||||||
for (int i = 0; i < colorAttCount; ++i) {
|
for (uint i = 0; i < uint(colorAttCount); ++i) {
|
||||||
rp.colorAttachments[i].loadAction = MTLLoadActionClear;
|
rp.colorAttachments[i].loadAction = MTLLoadActionClear;
|
||||||
rp.colorAttachments[i].storeAction = MTLStoreActionStore;
|
rp.colorAttachments[i].storeAction = MTLStoreActionStore;
|
||||||
rp.colorAttachments[i].clearColor = c;
|
rp.colorAttachments[i].clearColor = c;
|
||||||
@ -1413,7 +1421,7 @@ MTLRenderPassDescriptor *QRhiMetalData::createDefaultRenderPass(bool hasDepthSte
|
|||||||
rp.depthAttachment.storeAction = MTLStoreActionDontCare;
|
rp.depthAttachment.storeAction = MTLStoreActionDontCare;
|
||||||
rp.stencilAttachment.loadAction = MTLLoadActionClear;
|
rp.stencilAttachment.loadAction = MTLLoadActionClear;
|
||||||
rp.stencilAttachment.storeAction = MTLStoreActionDontCare;
|
rp.stencilAttachment.storeAction = MTLStoreActionDontCare;
|
||||||
rp.depthAttachment.clearDepth = depthStencilClearValue.depthClearValue();
|
rp.depthAttachment.clearDepth = double(depthStencilClearValue.depthClearValue());
|
||||||
rp.stencilAttachment.clearStencil = depthStencilClearValue.stencilClearValue();
|
rp.stencilAttachment.clearStencil = depthStencilClearValue.stencilClearValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1426,7 +1434,7 @@ qsizetype QRhiMetal::subresUploadByteSize(const QRhiTextureSubresourceUploadDesc
|
|||||||
const qsizetype imageSizeBytes = subresDesc.image().isNull() ?
|
const qsizetype imageSizeBytes = subresDesc.image().isNull() ?
|
||||||
subresDesc.data().size() : subresDesc.image().sizeInBytes();
|
subresDesc.data().size() : subresDesc.image().sizeInBytes();
|
||||||
if (imageSizeBytes > 0)
|
if (imageSizeBytes > 0)
|
||||||
size += aligned(imageSizeBytes, QRhiMetalData::TEXBUF_ALIGN);
|
size += aligned<qsizetype>(imageSizeBytes, QRhiMetalData::TEXBUF_ALIGN);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1454,31 +1462,31 @@ void QRhiMetal::enqueueSubresUpload(QMetalTexture *texD, void *mp, void *blitEnc
|
|||||||
h = subresDesc.sourceSize().height();
|
h = subresDesc.sourceSize().height();
|
||||||
}
|
}
|
||||||
if (img.depth() == 32) {
|
if (img.depth() == 32) {
|
||||||
memcpy(reinterpret_cast<char *>(mp) + *curOfs, img.constBits(), fullImageSizeBytes);
|
memcpy(reinterpret_cast<char *>(mp) + *curOfs, img.constBits(), size_t(fullImageSizeBytes));
|
||||||
srcOffset = sy * bpl + sx * 4;
|
srcOffset = sy * bpl + sx * 4;
|
||||||
// bpl remains set to the original image's row stride
|
// bpl remains set to the original image's row stride
|
||||||
} else {
|
} else {
|
||||||
img = img.copy(sx, sy, w, h);
|
img = img.copy(sx, sy, w, h);
|
||||||
bpl = img.bytesPerLine();
|
bpl = img.bytesPerLine();
|
||||||
Q_ASSERT(img.sizeInBytes() <= fullImageSizeBytes);
|
Q_ASSERT(img.sizeInBytes() <= fullImageSizeBytes);
|
||||||
memcpy(reinterpret_cast<char *>(mp) + *curOfs, img.constBits(), img.sizeInBytes());
|
memcpy(reinterpret_cast<char *>(mp) + *curOfs, img.constBits(), size_t(img.sizeInBytes()));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
memcpy(reinterpret_cast<char *>(mp) + *curOfs, img.constBits(), fullImageSizeBytes);
|
memcpy(reinterpret_cast<char *>(mp) + *curOfs, img.constBits(), size_t(fullImageSizeBytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
[blitEnc copyFromBuffer: texD->d->stagingBuf[currentFrameSlot]
|
[blitEnc copyFromBuffer: texD->d->stagingBuf[currentFrameSlot]
|
||||||
sourceOffset: *curOfs + srcOffset
|
sourceOffset: NSUInteger(*curOfs + srcOffset)
|
||||||
sourceBytesPerRow: bpl
|
sourceBytesPerRow: NSUInteger(bpl)
|
||||||
sourceBytesPerImage: 0
|
sourceBytesPerImage: 0
|
||||||
sourceSize: MTLSizeMake(w, h, 1)
|
sourceSize: MTLSizeMake(NSUInteger(w), NSUInteger(h), 1)
|
||||||
toTexture: texD->d->tex
|
toTexture: texD->d->tex
|
||||||
destinationSlice: layer
|
destinationSlice: NSUInteger(layer)
|
||||||
destinationLevel: level
|
destinationLevel: NSUInteger(level)
|
||||||
destinationOrigin: MTLOriginMake(dp.x(), dp.y(), 0)
|
destinationOrigin: MTLOriginMake(NSUInteger(dp.x()), NSUInteger(dp.y()), 0)
|
||||||
options: MTLBlitOptionNone];
|
options: MTLBlitOptionNone];
|
||||||
|
|
||||||
*curOfs += aligned(fullImageSizeBytes, QRhiMetalData::TEXBUF_ALIGN);
|
*curOfs += aligned<qsizetype>(fullImageSizeBytes, QRhiMetalData::TEXBUF_ALIGN);
|
||||||
} else if (!rawData.isEmpty() && isCompressedFormat(texD->m_format)) {
|
} else if (!rawData.isEmpty() && isCompressedFormat(texD->m_format)) {
|
||||||
const QSize subresSize = q->sizeForMipLevel(level, texD->m_pixelSize);
|
const QSize subresSize = q->sizeForMipLevel(level, texD->m_pixelSize);
|
||||||
const int subresw = subresSize.width();
|
const int subresw = subresSize.width();
|
||||||
@ -1503,17 +1511,17 @@ void QRhiMetal::enqueueSubresUpload(QMetalTexture *texD, void *mp, void *blitEnc
|
|||||||
if (dy + h != subresh)
|
if (dy + h != subresh)
|
||||||
h = aligned(h, blockDim.height());
|
h = aligned(h, blockDim.height());
|
||||||
|
|
||||||
memcpy(reinterpret_cast<char *>(mp) + *curOfs, rawData.constData(), rawData.size());
|
memcpy(reinterpret_cast<char *>(mp) + *curOfs, rawData.constData(), size_t(rawData.size()));
|
||||||
|
|
||||||
[blitEnc copyFromBuffer: texD->d->stagingBuf[currentFrameSlot]
|
[blitEnc copyFromBuffer: texD->d->stagingBuf[currentFrameSlot]
|
||||||
sourceOffset: *curOfs
|
sourceOffset: NSUInteger(*curOfs)
|
||||||
sourceBytesPerRow: bpl
|
sourceBytesPerRow: bpl
|
||||||
sourceBytesPerImage: 0
|
sourceBytesPerImage: 0
|
||||||
sourceSize: MTLSizeMake(w, h, 1)
|
sourceSize: MTLSizeMake(NSUInteger(w), NSUInteger(h), 1)
|
||||||
toTexture: texD->d->tex
|
toTexture: texD->d->tex
|
||||||
destinationSlice: layer
|
destinationSlice: NSUInteger(layer)
|
||||||
destinationLevel: level
|
destinationLevel: NSUInteger(level)
|
||||||
destinationOrigin: MTLOriginMake(dx, dy, 0)
|
destinationOrigin: MTLOriginMake(NSUInteger(dx), NSUInteger(dy), 0)
|
||||||
options: MTLBlitOptionNone];
|
options: MTLBlitOptionNone];
|
||||||
|
|
||||||
*curOfs += aligned(rawData.size(), QRhiMetalData::TEXBUF_ALIGN);
|
*curOfs += aligned(rawData.size(), QRhiMetalData::TEXBUF_ALIGN);
|
||||||
@ -1532,17 +1540,17 @@ void QRhiMetal::enqueueSubresUpload(QMetalTexture *texD, void *mp, void *blitEnc
|
|||||||
|
|
||||||
quint32 bpl = 0;
|
quint32 bpl = 0;
|
||||||
textureFormatInfo(texD->m_format, QSize(w, h), &bpl, nullptr);
|
textureFormatInfo(texD->m_format, QSize(w, h), &bpl, nullptr);
|
||||||
memcpy(reinterpret_cast<char *>(mp) + *curOfs, rawData.constData(), rawData.size());
|
memcpy(reinterpret_cast<char *>(mp) + *curOfs, rawData.constData(), size_t(rawData.size()));
|
||||||
|
|
||||||
[blitEnc copyFromBuffer: texD->d->stagingBuf[currentFrameSlot]
|
[blitEnc copyFromBuffer: texD->d->stagingBuf[currentFrameSlot]
|
||||||
sourceOffset: *curOfs
|
sourceOffset: NSUInteger(*curOfs)
|
||||||
sourceBytesPerRow: bpl
|
sourceBytesPerRow: bpl
|
||||||
sourceBytesPerImage: 0
|
sourceBytesPerImage: 0
|
||||||
sourceSize: MTLSizeMake(w, h, 1)
|
sourceSize: MTLSizeMake(NSUInteger(w), NSUInteger(h), 1)
|
||||||
toTexture: texD->d->tex
|
toTexture: texD->d->tex
|
||||||
destinationSlice: layer
|
destinationSlice: NSUInteger(layer)
|
||||||
destinationLevel: level
|
destinationLevel: NSUInteger(level)
|
||||||
destinationOrigin: MTLOriginMake(dp.x(), dp.y(), 0)
|
destinationOrigin: MTLOriginMake(NSUInteger(dp.x()), NSUInteger(dp.y()), 0)
|
||||||
options: MTLBlitOptionNone];
|
options: MTLBlitOptionNone];
|
||||||
|
|
||||||
*curOfs += aligned(rawData.size(), QRhiMetalData::TEXBUF_ALIGN);
|
*curOfs += aligned(rawData.size(), QRhiMetalData::TEXBUF_ALIGN);
|
||||||
@ -1596,9 +1604,9 @@ void QRhiMetal::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
|
|||||||
|
|
||||||
ensureBlit();
|
ensureBlit();
|
||||||
Q_ASSERT(!utexD->d->stagingBuf[currentFrameSlot]);
|
Q_ASSERT(!utexD->d->stagingBuf[currentFrameSlot]);
|
||||||
utexD->d->stagingBuf[currentFrameSlot] = [d->dev newBufferWithLength: stagingSize
|
utexD->d->stagingBuf[currentFrameSlot] = [d->dev newBufferWithLength: NSUInteger(stagingSize)
|
||||||
options: MTLResourceStorageModeShared];
|
options: MTLResourceStorageModeShared];
|
||||||
QRHI_PROF_F(newTextureStagingArea(utexD, currentFrameSlot, stagingSize));
|
QRHI_PROF_F(newTextureStagingArea(utexD, currentFrameSlot, quint32(stagingSize)));
|
||||||
|
|
||||||
void *mp = [utexD->d->stagingBuf[currentFrameSlot] contents];
|
void *mp = [utexD->d->stagingBuf[currentFrameSlot] contents];
|
||||||
qsizetype curOfs = 0;
|
qsizetype curOfs = 0;
|
||||||
@ -1628,14 +1636,14 @@ void QRhiMetal::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
|
|||||||
|
|
||||||
ensureBlit();
|
ensureBlit();
|
||||||
[blitEnc copyFromTexture: srcD->d->tex
|
[blitEnc copyFromTexture: srcD->d->tex
|
||||||
sourceSlice: u.copy.desc.sourceLayer()
|
sourceSlice: NSUInteger(u.copy.desc.sourceLayer())
|
||||||
sourceLevel: u.copy.desc.sourceLevel()
|
sourceLevel: NSUInteger(u.copy.desc.sourceLevel())
|
||||||
sourceOrigin: MTLOriginMake(sp.x(), sp.y(), 0)
|
sourceOrigin: MTLOriginMake(NSUInteger(sp.x()), NSUInteger(sp.y()), 0)
|
||||||
sourceSize: MTLSizeMake(size.width(), size.height(), 1)
|
sourceSize: MTLSizeMake(NSUInteger(size.width()), NSUInteger(size.height()), 1)
|
||||||
toTexture: dstD->d->tex
|
toTexture: dstD->d->tex
|
||||||
destinationSlice: u.copy.desc.destinationLayer()
|
destinationSlice: NSUInteger(u.copy.desc.destinationLayer())
|
||||||
destinationLevel: u.copy.desc.destinationLevel()
|
destinationLevel: NSUInteger(u.copy.desc.destinationLevel())
|
||||||
destinationOrigin: MTLOriginMake(dp.x(), dp.y(), 0)];
|
destinationOrigin: MTLOriginMake(NSUInteger(dp.x()), NSUInteger(dp.y()), 0)];
|
||||||
|
|
||||||
srcD->lastActiveFrameSlot = dstD->lastActiveFrameSlot = currentFrameSlot;
|
srcD->lastActiveFrameSlot = dstD->lastActiveFrameSlot = currentFrameSlot;
|
||||||
} else if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::Read) {
|
} else if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::Read) {
|
||||||
@ -1675,16 +1683,16 @@ void QRhiMetal::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
|
|||||||
textureFormatInfo(aRb.format, aRb.pixelSize, &bpl, &aRb.bufSize);
|
textureFormatInfo(aRb.format, aRb.pixelSize, &bpl, &aRb.bufSize);
|
||||||
aRb.buf = [d->dev newBufferWithLength: aRb.bufSize options: MTLResourceStorageModeShared];
|
aRb.buf = [d->dev newBufferWithLength: aRb.bufSize options: MTLResourceStorageModeShared];
|
||||||
|
|
||||||
QRHI_PROF_F(newReadbackBuffer(quint64(quintptr(aRb.buf)),
|
QRHI_PROF_F(newReadbackBuffer(qint64(qintptr(aRb.buf)),
|
||||||
texD ? static_cast<QRhiResource *>(texD) : static_cast<QRhiResource *>(swapChainD),
|
texD ? static_cast<QRhiResource *>(texD) : static_cast<QRhiResource *>(swapChainD),
|
||||||
aRb.bufSize));
|
aRb.bufSize));
|
||||||
|
|
||||||
ensureBlit();
|
ensureBlit();
|
||||||
[blitEnc copyFromTexture: src
|
[blitEnc copyFromTexture: src
|
||||||
sourceSlice: u.read.rb.layer()
|
sourceSlice: NSUInteger(u.read.rb.layer())
|
||||||
sourceLevel: u.read.rb.level()
|
sourceLevel: NSUInteger(u.read.rb.level())
|
||||||
sourceOrigin: MTLOriginMake(0, 0, 0)
|
sourceOrigin: MTLOriginMake(0, 0, 0)
|
||||||
sourceSize: MTLSizeMake(srcSize.width(), srcSize.height(), 1)
|
sourceSize: MTLSizeMake(NSUInteger(srcSize.width()), NSUInteger(srcSize.height()), 1)
|
||||||
toBuffer: aRb.buf
|
toBuffer: aRb.buf
|
||||||
destinationOffset: 0
|
destinationOffset: 0
|
||||||
destinationBytesPerRow: bpl
|
destinationBytesPerRow: bpl
|
||||||
@ -1722,14 +1730,14 @@ void QRhiMetal::executeBufferHostWritesForCurrentFrame(QMetalBuffer *bufD)
|
|||||||
int changeEnd = -1;
|
int changeEnd = -1;
|
||||||
for (const QRhiResourceUpdateBatchPrivate::DynamicBufferUpdate &u : updates) {
|
for (const QRhiResourceUpdateBatchPrivate::DynamicBufferUpdate &u : updates) {
|
||||||
Q_ASSERT(bufD == QRHI_RES(QMetalBuffer, u.buf));
|
Q_ASSERT(bufD == QRHI_RES(QMetalBuffer, u.buf));
|
||||||
memcpy(static_cast<char *>(p) + u.offset, u.data.constData(), u.data.size());
|
memcpy(static_cast<char *>(p) + u.offset, u.data.constData(), size_t(u.data.size()));
|
||||||
if (changeBegin == -1 || u.offset < changeBegin)
|
if (changeBegin == -1 || u.offset < changeBegin)
|
||||||
changeBegin = u.offset;
|
changeBegin = u.offset;
|
||||||
if (changeEnd == -1 || u.offset + u.data.size() > changeEnd)
|
if (changeEnd == -1 || u.offset + u.data.size() > changeEnd)
|
||||||
changeEnd = u.offset + u.data.size();
|
changeEnd = u.offset + u.data.size();
|
||||||
}
|
}
|
||||||
if (changeBegin >= 0 && bufD->d->managed)
|
if (changeBegin >= 0 && bufD->d->managed)
|
||||||
[bufD->d->buf[idx] didModifyRange: NSMakeRange(changeBegin, changeEnd - changeBegin)];
|
[bufD->d->buf[idx] didModifyRange: NSMakeRange(NSUInteger(changeBegin), NSUInteger(changeEnd - changeBegin))];
|
||||||
|
|
||||||
updates.clear();
|
updates.clear();
|
||||||
}
|
}
|
||||||
@ -1786,7 +1794,7 @@ void QRhiMetal::beginPass(QRhiCommandBuffer *cb,
|
|||||||
rtD = rtTex->d;
|
rtD = rtTex->d;
|
||||||
cbD->d->currentPassRpDesc = d->createDefaultRenderPass(rtD->dsAttCount, colorClearValue, depthStencilClearValue, rtD->colorAttCount);
|
cbD->d->currentPassRpDesc = d->createDefaultRenderPass(rtD->dsAttCount, colorClearValue, depthStencilClearValue, rtD->colorAttCount);
|
||||||
if (rtTex->m_flags.testFlag(QRhiTextureRenderTarget::PreserveColorContents)) {
|
if (rtTex->m_flags.testFlag(QRhiTextureRenderTarget::PreserveColorContents)) {
|
||||||
for (int i = 0; i < rtD->colorAttCount; ++i)
|
for (uint i = 0; i < uint(rtD->colorAttCount); ++i)
|
||||||
cbD->d->currentPassRpDesc.colorAttachments[i].loadAction = MTLLoadActionLoad;
|
cbD->d->currentPassRpDesc.colorAttachments[i].loadAction = MTLLoadActionLoad;
|
||||||
}
|
}
|
||||||
if (rtD->dsAttCount && rtTex->m_flags.testFlag(QRhiTextureRenderTarget::PreserveDepthStencilContents)) {
|
if (rtD->dsAttCount && rtTex->m_flags.testFlag(QRhiTextureRenderTarget::PreserveDepthStencilContents)) {
|
||||||
@ -1813,15 +1821,15 @@ void QRhiMetal::beginPass(QRhiCommandBuffer *cb,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < rtD->colorAttCount; ++i) {
|
for (uint i = 0; i < uint(rtD->colorAttCount); ++i) {
|
||||||
cbD->d->currentPassRpDesc.colorAttachments[i].texture = rtD->fb.colorAtt[i].tex;
|
cbD->d->currentPassRpDesc.colorAttachments[i].texture = rtD->fb.colorAtt[i].tex;
|
||||||
cbD->d->currentPassRpDesc.colorAttachments[i].slice = rtD->fb.colorAtt[i].layer;
|
cbD->d->currentPassRpDesc.colorAttachments[i].slice = NSUInteger(rtD->fb.colorAtt[i].layer);
|
||||||
cbD->d->currentPassRpDesc.colorAttachments[i].level = rtD->fb.colorAtt[i].level;
|
cbD->d->currentPassRpDesc.colorAttachments[i].level = NSUInteger(rtD->fb.colorAtt[i].level);
|
||||||
if (rtD->fb.colorAtt[i].resolveTex) {
|
if (rtD->fb.colorAtt[i].resolveTex) {
|
||||||
cbD->d->currentPassRpDesc.colorAttachments[i].storeAction = MTLStoreActionMultisampleResolve;
|
cbD->d->currentPassRpDesc.colorAttachments[i].storeAction = MTLStoreActionMultisampleResolve;
|
||||||
cbD->d->currentPassRpDesc.colorAttachments[i].resolveTexture = rtD->fb.colorAtt[i].resolveTex;
|
cbD->d->currentPassRpDesc.colorAttachments[i].resolveTexture = rtD->fb.colorAtt[i].resolveTex;
|
||||||
cbD->d->currentPassRpDesc.colorAttachments[i].resolveSlice = rtD->fb.colorAtt[i].resolveLayer;
|
cbD->d->currentPassRpDesc.colorAttachments[i].resolveSlice = NSUInteger(rtD->fb.colorAtt[i].resolveLayer);
|
||||||
cbD->d->currentPassRpDesc.colorAttachments[i].resolveLevel = rtD->fb.colorAtt[i].resolveLevel;
|
cbD->d->currentPassRpDesc.colorAttachments[i].resolveLevel = NSUInteger(rtD->fb.colorAtt[i].resolveLevel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1903,7 +1911,7 @@ void QRhiMetal::dispatch(QRhiCommandBuffer *cb, int x, int y, int z)
|
|||||||
Q_ASSERT(cbD->recordingPass == QMetalCommandBuffer::ComputePass);
|
Q_ASSERT(cbD->recordingPass == QMetalCommandBuffer::ComputePass);
|
||||||
QMetalComputePipeline *psD = QRHI_RES(QMetalComputePipeline, cbD->currentComputePipeline);
|
QMetalComputePipeline *psD = QRHI_RES(QMetalComputePipeline, cbD->currentComputePipeline);
|
||||||
|
|
||||||
[cbD->d->currentComputePassEncoder dispatchThreadgroups: MTLSizeMake(x, y, z)
|
[cbD->d->currentComputePassEncoder dispatchThreadgroups: MTLSizeMake(NSUInteger(x), NSUInteger(y), NSUInteger(z))
|
||||||
threadsPerThreadgroup: psD->d->localSize];
|
threadsPerThreadgroup: psD->d->localSize];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1971,12 +1979,12 @@ void QRhiMetal::finishActiveReadbacks(bool forced)
|
|||||||
if (forced || currentFrameSlot == aRb.activeFrameSlot || aRb.activeFrameSlot < 0) {
|
if (forced || currentFrameSlot == aRb.activeFrameSlot || aRb.activeFrameSlot < 0) {
|
||||||
aRb.result->format = aRb.format;
|
aRb.result->format = aRb.format;
|
||||||
aRb.result->pixelSize = aRb.pixelSize;
|
aRb.result->pixelSize = aRb.pixelSize;
|
||||||
aRb.result->data.resize(aRb.bufSize);
|
aRb.result->data.resize(int(aRb.bufSize));
|
||||||
void *p = [aRb.buf contents];
|
void *p = [aRb.buf contents];
|
||||||
memcpy(aRb.result->data.data(), p, aRb.bufSize);
|
memcpy(aRb.result->data.data(), p, aRb.bufSize);
|
||||||
[aRb.buf release];
|
[aRb.buf release];
|
||||||
|
|
||||||
QRHI_PROF_F(releaseReadbackBuffer(quint64(quintptr(aRb.buf))));
|
QRHI_PROF_F(releaseReadbackBuffer(qint64(qintptr(aRb.buf))));
|
||||||
|
|
||||||
if (aRb.result->completed)
|
if (aRb.result->completed)
|
||||||
completedCallbacks.append(aRb.result->completed);
|
completedCallbacks.append(aRb.result->completed);
|
||||||
@ -2035,8 +2043,8 @@ bool QMetalBuffer::build()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int nonZeroSize = m_size <= 0 ? 256 : m_size;
|
const uint nonZeroSize = m_size <= 0 ? 256 : uint(m_size);
|
||||||
const int roundedSize = m_usage.testFlag(QRhiBuffer::UniformBuffer) ? aligned(nonZeroSize, 256) : nonZeroSize;
|
const uint roundedSize = m_usage.testFlag(QRhiBuffer::UniformBuffer) ? aligned<uint>(nonZeroSize, 256) : nonZeroSize;
|
||||||
|
|
||||||
d->managed = false;
|
d->managed = false;
|
||||||
MTLResourceOptions opts = MTLResourceStorageModeShared;
|
MTLResourceOptions opts = MTLResourceStorageModeShared;
|
||||||
@ -2123,10 +2131,10 @@ bool QMetalRenderBuffer::build()
|
|||||||
|
|
||||||
MTLTextureDescriptor *desc = [[MTLTextureDescriptor alloc] init];
|
MTLTextureDescriptor *desc = [[MTLTextureDescriptor alloc] init];
|
||||||
desc.textureType = samples > 1 ? MTLTextureType2DMultisample : MTLTextureType2D;
|
desc.textureType = samples > 1 ? MTLTextureType2DMultisample : MTLTextureType2D;
|
||||||
desc.width = m_pixelSize.width();
|
desc.width = NSUInteger(m_pixelSize.width());
|
||||||
desc.height = m_pixelSize.height();
|
desc.height = NSUInteger(m_pixelSize.height());
|
||||||
if (samples > 1)
|
if (samples > 1)
|
||||||
desc.sampleCount = samples;
|
desc.sampleCount = NSUInteger(samples);
|
||||||
desc.resourceOptions = MTLResourceStorageModePrivate;
|
desc.resourceOptions = MTLResourceStorageModePrivate;
|
||||||
desc.usage = MTLTextureUsageRenderTarget;
|
desc.usage = MTLTextureUsageRenderTarget;
|
||||||
|
|
||||||
@ -2393,11 +2401,11 @@ bool QMetalTexture::build()
|
|||||||
else
|
else
|
||||||
desc.textureType = samples > 1 ? MTLTextureType2DMultisample : MTLTextureType2D;
|
desc.textureType = samples > 1 ? MTLTextureType2DMultisample : MTLTextureType2D;
|
||||||
desc.pixelFormat = d->format;
|
desc.pixelFormat = d->format;
|
||||||
desc.width = size.width();
|
desc.width = NSUInteger(size.width());
|
||||||
desc.height = size.height();
|
desc.height = NSUInteger(size.height());
|
||||||
desc.mipmapLevelCount = mipLevelCount;
|
desc.mipmapLevelCount = NSUInteger(mipLevelCount);
|
||||||
if (samples > 1)
|
if (samples > 1)
|
||||||
desc.sampleCount = samples;
|
desc.sampleCount = NSUInteger(samples);
|
||||||
desc.resourceOptions = MTLResourceStorageModePrivate;
|
desc.resourceOptions = MTLResourceStorageModePrivate;
|
||||||
desc.storageMode = MTLStorageModePrivate;
|
desc.storageMode = MTLStorageModePrivate;
|
||||||
desc.usage = MTLTextureUsageShaderRead;
|
desc.usage = MTLTextureUsageShaderRead;
|
||||||
@ -2463,7 +2471,7 @@ id<MTLTexture> QMetalTextureData::viewForLevel(int level)
|
|||||||
const MTLTextureType type = [tex textureType];
|
const MTLTextureType type = [tex textureType];
|
||||||
const bool isCube = q->m_flags.testFlag(QRhiTexture::CubeMap);
|
const bool isCube = q->m_flags.testFlag(QRhiTexture::CubeMap);
|
||||||
id<MTLTexture> view = [tex newTextureViewWithPixelFormat: format textureType: type
|
id<MTLTexture> view = [tex newTextureViewWithPixelFormat: format textureType: type
|
||||||
levels: NSMakeRange(level, 1) slices: NSMakeRange(0, isCube ? 6 : 1)];
|
levels: NSMakeRange(NSUInteger(level), 1) slices: NSMakeRange(0, isCube ? 6 : 1)];
|
||||||
|
|
||||||
perLevelViews[level] = view;
|
perLevelViews[level] = view;
|
||||||
return view;
|
return view;
|
||||||
@ -2673,13 +2681,13 @@ QRhiRenderPassDescriptor *QMetalTextureRenderTarget::newCompatibleRenderPassDesc
|
|||||||
for (int i = 0, ie = colorAttachments.count(); i != ie; ++i) {
|
for (int i = 0, ie = colorAttachments.count(); i != ie; ++i) {
|
||||||
QMetalTexture *texD = QRHI_RES(QMetalTexture, colorAttachments[i].texture());
|
QMetalTexture *texD = QRHI_RES(QMetalTexture, colorAttachments[i].texture());
|
||||||
QMetalRenderBuffer *rbD = QRHI_RES(QMetalRenderBuffer, colorAttachments[i].renderBuffer());
|
QMetalRenderBuffer *rbD = QRHI_RES(QMetalRenderBuffer, colorAttachments[i].renderBuffer());
|
||||||
rpD->colorFormat[i] = texD ? texD->d->format : rbD->d->format;
|
rpD->colorFormat[i] = int(texD ? texD->d->format : rbD->d->format);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_desc.depthTexture())
|
if (m_desc.depthTexture())
|
||||||
rpD->dsFormat = QRHI_RES(QMetalTexture, m_desc.depthTexture())->d->format;
|
rpD->dsFormat = int(QRHI_RES(QMetalTexture, m_desc.depthTexture())->d->format);
|
||||||
else if (m_desc.depthStencilBuffer())
|
else if (m_desc.depthStencilBuffer())
|
||||||
rpD->dsFormat = QRHI_RES(QMetalRenderBuffer, m_desc.depthStencilBuffer())->d->format;
|
rpD->dsFormat = int(QRHI_RES(QMetalRenderBuffer, m_desc.depthStencilBuffer())->d->format);
|
||||||
|
|
||||||
return rpD;
|
return rpD;
|
||||||
}
|
}
|
||||||
@ -3079,7 +3087,7 @@ id<MTLLibrary> QRhiMetalData::createMetalLib(const QShader &shader, QShader::Var
|
|||||||
QShaderCode mtllib = shader.shader({ QShader::MetalLibShader, 12, shaderVariant });
|
QShaderCode mtllib = shader.shader({ QShader::MetalLibShader, 12, shaderVariant });
|
||||||
if (!mtllib.shader().isEmpty()) {
|
if (!mtllib.shader().isEmpty()) {
|
||||||
dispatch_data_t data = dispatch_data_create(mtllib.shader().constData(),
|
dispatch_data_t data = dispatch_data_create(mtllib.shader().constData(),
|
||||||
mtllib.shader().size(),
|
size_t(mtllib.shader().size()),
|
||||||
dispatch_get_global_queue(0, 0),
|
dispatch_get_global_queue(0, 0),
|
||||||
DISPATCH_DATA_DESTRUCTOR_DEFAULT);
|
DISPATCH_DATA_DESTRUCTOR_DEFAULT);
|
||||||
NSError *err = nil;
|
NSError *err = nil;
|
||||||
@ -3139,19 +3147,19 @@ bool QMetalGraphicsPipeline::build()
|
|||||||
MTLVertexDescriptor *inputLayout = [MTLVertexDescriptor vertexDescriptor];
|
MTLVertexDescriptor *inputLayout = [MTLVertexDescriptor vertexDescriptor];
|
||||||
const QVector<QRhiVertexInputAttribute> attributes = m_vertexInputLayout.attributes();
|
const QVector<QRhiVertexInputAttribute> attributes = m_vertexInputLayout.attributes();
|
||||||
for (const QRhiVertexInputAttribute &attribute : attributes) {
|
for (const QRhiVertexInputAttribute &attribute : attributes) {
|
||||||
const int loc = attribute.location();
|
const uint loc = uint(attribute.location());
|
||||||
inputLayout.attributes[loc].format = toMetalAttributeFormat(attribute.format());
|
inputLayout.attributes[loc].format = toMetalAttributeFormat(attribute.format());
|
||||||
inputLayout.attributes[loc].offset = attribute.offset();
|
inputLayout.attributes[loc].offset = NSUInteger(attribute.offset());
|
||||||
inputLayout.attributes[loc].bufferIndex = firstVertexBinding + attribute.binding();
|
inputLayout.attributes[loc].bufferIndex = NSUInteger(firstVertexBinding + attribute.binding());
|
||||||
}
|
}
|
||||||
const QVector<QRhiVertexInputBinding> bindings = m_vertexInputLayout.bindings();
|
const QVector<QRhiVertexInputBinding> bindings = m_vertexInputLayout.bindings();
|
||||||
for (int i = 0, ie = bindings.count(); i != ie; ++i) {
|
for (int i = 0, ie = bindings.count(); i != ie; ++i) {
|
||||||
const QRhiVertexInputBinding &binding(bindings[i]);
|
const QRhiVertexInputBinding &binding(bindings[i]);
|
||||||
const int layoutIdx = firstVertexBinding + i;
|
const uint layoutIdx = uint(firstVertexBinding + i);
|
||||||
inputLayout.layouts[layoutIdx].stepFunction =
|
inputLayout.layouts[layoutIdx].stepFunction =
|
||||||
binding.classification() == QRhiVertexInputBinding::PerInstance
|
binding.classification() == QRhiVertexInputBinding::PerInstance
|
||||||
? MTLVertexStepFunctionPerInstance : MTLVertexStepFunctionPerVertex;
|
? MTLVertexStepFunctionPerInstance : MTLVertexStepFunctionPerVertex;
|
||||||
inputLayout.layouts[layoutIdx].stepRate = binding.instanceStepRate();
|
inputLayout.layouts[layoutIdx].stepRate = NSUInteger(binding.instanceStepRate());
|
||||||
inputLayout.layouts[layoutIdx].stride = binding.stride();
|
inputLayout.layouts[layoutIdx].stride = binding.stride();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3239,8 +3247,8 @@ bool QMetalGraphicsPipeline::build()
|
|||||||
Q_ASSERT(m_targetBlends.count() == rpD->colorAttachmentCount
|
Q_ASSERT(m_targetBlends.count() == rpD->colorAttachmentCount
|
||||||
|| (m_targetBlends.isEmpty() && rpD->colorAttachmentCount == 1));
|
|| (m_targetBlends.isEmpty() && rpD->colorAttachmentCount == 1));
|
||||||
|
|
||||||
for (int i = 0, ie = m_targetBlends.count(); i != ie; ++i) {
|
for (uint i = 0, ie = uint(m_targetBlends.count()); i != ie; ++i) {
|
||||||
const QRhiGraphicsPipeline::TargetBlend &b(m_targetBlends[i]);
|
const QRhiGraphicsPipeline::TargetBlend &b(m_targetBlends[int(i)]);
|
||||||
rpDesc.colorAttachments[i].pixelFormat = MTLPixelFormat(rpD->colorFormat[i]);
|
rpDesc.colorAttachments[i].pixelFormat = MTLPixelFormat(rpD->colorFormat[i]);
|
||||||
rpDesc.colorAttachments[i].blendingEnabled = b.enable;
|
rpDesc.colorAttachments[i].blendingEnabled = b.enable;
|
||||||
rpDesc.colorAttachments[i].sourceRGBBlendFactor = toMetalBlendFactor(b.srcColor);
|
rpDesc.colorAttachments[i].sourceRGBBlendFactor = toMetalBlendFactor(b.srcColor);
|
||||||
@ -3262,7 +3270,7 @@ bool QMetalGraphicsPipeline::build()
|
|||||||
rpDesc.stencilAttachmentPixelFormat = fmt;
|
rpDesc.stencilAttachmentPixelFormat = fmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
rpDesc.sampleCount = rhiD->effectiveSampleCount(m_sampleCount);
|
rpDesc.sampleCount = NSUInteger(rhiD->effectiveSampleCount(m_sampleCount));
|
||||||
|
|
||||||
NSError *err = nil;
|
NSError *err = nil;
|
||||||
d->ps = [rhiD->d->dev newRenderPipelineStateWithDescriptor: rpDesc error: &err];
|
d->ps = [rhiD->d->dev newRenderPipelineStateWithDescriptor: rpDesc error: &err];
|
||||||
@ -3517,7 +3525,7 @@ QSize QMetalSwapChain::surfacePixelSize()
|
|||||||
CAMetalLayer *layer = (CAMetalLayer *) [v layer];
|
CAMetalLayer *layer = (CAMetalLayer *) [v layer];
|
||||||
if (layer) {
|
if (layer) {
|
||||||
CGSize size = [layer drawableSize];
|
CGSize size = [layer drawableSize];
|
||||||
return QSize(size.width, size.height);
|
return QSize(int(size.width), int(size.height));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return QSize();
|
return QSize();
|
||||||
@ -3532,7 +3540,7 @@ QRhiRenderPassDescriptor *QMetalSwapChain::newCompatibleRenderPassDescriptor()
|
|||||||
rpD->colorAttachmentCount = 1;
|
rpD->colorAttachmentCount = 1;
|
||||||
rpD->hasDepthStencil = m_depthStencil != nullptr;
|
rpD->hasDepthStencil = m_depthStencil != nullptr;
|
||||||
|
|
||||||
rpD->colorFormat[0] = d->colorFormat;
|
rpD->colorFormat[0] = int(d->colorFormat);
|
||||||
|
|
||||||
// m_depthStencil may not be built yet so cannot rely on computed fields in it
|
// m_depthStencil may not be built yet so cannot rely on computed fields in it
|
||||||
rpD->dsFormat = rhiD->d->dev.depth24Stencil8PixelFormatSupported
|
rpD->dsFormat = rhiD->d->dev.depth24Stencil8PixelFormatSupported
|
||||||
@ -3589,6 +3597,18 @@ bool QMetalSwapChain::buildOrResize()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (m_flags.testFlag(SurfaceHasPreMulAlpha)) {
|
||||||
|
d->layer.opaque = NO;
|
||||||
|
} else if (m_flags.testFlag(SurfaceHasNonPreMulAlpha)) {
|
||||||
|
// The CoreAnimation compositor is said to expect premultiplied alpha,
|
||||||
|
// so this is then wrong when it comes to the blending operations but
|
||||||
|
// there's nothing we can do. Fortunately Qt Quick always outputs
|
||||||
|
// premultiplied alpha so it is not a problem there.
|
||||||
|
d->layer.opaque = NO;
|
||||||
|
} else {
|
||||||
|
d->layer.opaque = YES;
|
||||||
|
}
|
||||||
|
|
||||||
m_currentPixelSize = surfacePixelSize();
|
m_currentPixelSize = surfacePixelSize();
|
||||||
pixelSize = m_currentPixelSize;
|
pixelSize = m_currentPixelSize;
|
||||||
|
|
||||||
@ -3616,7 +3636,7 @@ bool QMetalSwapChain::buildOrResize()
|
|||||||
}
|
}
|
||||||
|
|
||||||
rtWrapper.d->pixelSize = pixelSize;
|
rtWrapper.d->pixelSize = pixelSize;
|
||||||
rtWrapper.d->dpr = window->devicePixelRatio();
|
rtWrapper.d->dpr = float(window->devicePixelRatio());
|
||||||
rtWrapper.d->sampleCount = samples;
|
rtWrapper.d->sampleCount = samples;
|
||||||
rtWrapper.d->colorAttCount = 1;
|
rtWrapper.d->colorAttCount = 1;
|
||||||
rtWrapper.d->dsAttCount = ds ? 1 : 0;
|
rtWrapper.d->dsAttCount = ds ? 1 : 0;
|
||||||
@ -3627,9 +3647,9 @@ bool QMetalSwapChain::buildOrResize()
|
|||||||
MTLTextureDescriptor *desc = [[MTLTextureDescriptor alloc] init];
|
MTLTextureDescriptor *desc = [[MTLTextureDescriptor alloc] init];
|
||||||
desc.textureType = MTLTextureType2DMultisample;
|
desc.textureType = MTLTextureType2DMultisample;
|
||||||
desc.pixelFormat = d->colorFormat;
|
desc.pixelFormat = d->colorFormat;
|
||||||
desc.width = pixelSize.width();
|
desc.width = NSUInteger(pixelSize.width());
|
||||||
desc.height = pixelSize.height();
|
desc.height = NSUInteger(pixelSize.height());
|
||||||
desc.sampleCount = samples;
|
desc.sampleCount = NSUInteger(samples);
|
||||||
desc.resourceOptions = MTLResourceStorageModePrivate;
|
desc.resourceOptions = MTLResourceStorageModePrivate;
|
||||||
desc.storageMode = MTLStorageModePrivate;
|
desc.storageMode = MTLStorageModePrivate;
|
||||||
desc.usage = MTLTextureUsageRenderTarget;
|
desc.usage = MTLTextureUsageRenderTarget;
|
||||||
|
@ -416,8 +416,9 @@ public:
|
|||||||
int resourceLimit(QRhi::ResourceLimit limit) const override;
|
int resourceLimit(QRhi::ResourceLimit limit) const override;
|
||||||
const QRhiNativeHandles *nativeHandles() override;
|
const QRhiNativeHandles *nativeHandles() override;
|
||||||
void sendVMemStatsToProfiler() override;
|
void sendVMemStatsToProfiler() override;
|
||||||
void makeThreadLocalNativeContextCurrent() override;
|
bool makeThreadLocalNativeContextCurrent() override;
|
||||||
void releaseCachedResources() override;
|
void releaseCachedResources() override;
|
||||||
|
bool isDeviceLost() const override;
|
||||||
|
|
||||||
void executeDeferredReleases(bool forced = false);
|
void executeDeferredReleases(bool forced = false);
|
||||||
void finishActiveReadbacks(bool forced = false);
|
void finishActiveReadbacks(bool forced = false);
|
||||||
|
@ -169,9 +169,10 @@ void QRhiNull::sendVMemStatsToProfiler()
|
|||||||
// nothing to do here
|
// nothing to do here
|
||||||
}
|
}
|
||||||
|
|
||||||
void QRhiNull::makeThreadLocalNativeContextCurrent()
|
bool QRhiNull::makeThreadLocalNativeContextCurrent()
|
||||||
{
|
{
|
||||||
// nothing to do here
|
// not applicable
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QRhiNull::releaseCachedResources()
|
void QRhiNull::releaseCachedResources()
|
||||||
@ -179,6 +180,11 @@ void QRhiNull::releaseCachedResources()
|
|||||||
// nothing to do here
|
// nothing to do here
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QRhiNull::isDeviceLost() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
QRhiRenderBuffer *QRhiNull::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
|
QRhiRenderBuffer *QRhiNull::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
|
||||||
int sampleCount, QRhiRenderBuffer::Flags flags)
|
int sampleCount, QRhiRenderBuffer::Flags flags)
|
||||||
{
|
{
|
||||||
|
@ -282,8 +282,9 @@ public:
|
|||||||
int resourceLimit(QRhi::ResourceLimit limit) const override;
|
int resourceLimit(QRhi::ResourceLimit limit) const override;
|
||||||
const QRhiNativeHandles *nativeHandles() override;
|
const QRhiNativeHandles *nativeHandles() override;
|
||||||
void sendVMemStatsToProfiler() override;
|
void sendVMemStatsToProfiler() override;
|
||||||
void makeThreadLocalNativeContextCurrent() override;
|
bool makeThreadLocalNativeContextCurrent() override;
|
||||||
void releaseCachedResources() override;
|
void releaseCachedResources() override;
|
||||||
|
bool isDeviceLost() const override;
|
||||||
|
|
||||||
QRhiNullNativeHandles nativeHandlesStruct;
|
QRhiNullNativeHandles nativeHandlesStruct;
|
||||||
QRhiSwapChain *currentSwapChain = nullptr;
|
QRhiSwapChain *currentSwapChain = nullptr;
|
||||||
|
@ -319,7 +319,7 @@ void QRhiProfilerPrivate::writeFloat(const char *key, float f)
|
|||||||
Q_ASSERT(key[0] == 'F');
|
Q_ASSERT(key[0] == 'F');
|
||||||
buf.append(key);
|
buf.append(key);
|
||||||
buf.append(',');
|
buf.append(',');
|
||||||
buf.append(QByteArray::number(f));
|
buf.append(QByteArray::number(double(f)));
|
||||||
buf.append(',');
|
buf.append(',');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -385,7 +385,7 @@ void QRhiProfilerPrivate::newRenderBuffer(QRhiRenderBuffer *rb, bool transientBa
|
|||||||
const QRhiTexture::Format assumedFormat = type == QRhiRenderBuffer::DepthStencil ? QRhiTexture::D32F : QRhiTexture::RGBA8;
|
const QRhiTexture::Format assumedFormat = type == QRhiRenderBuffer::DepthStencil ? QRhiTexture::D32F : QRhiTexture::RGBA8;
|
||||||
quint32 byteSize = rhiDWhenEnabled->approxByteSizeForTexture(assumedFormat, sz, 1, 1);
|
quint32 byteSize = rhiDWhenEnabled->approxByteSizeForTexture(assumedFormat, sz, 1, 1);
|
||||||
if (sampleCount > 1)
|
if (sampleCount > 1)
|
||||||
byteSize *= sampleCount;
|
byteSize *= uint(sampleCount);
|
||||||
|
|
||||||
startEntry(QRhiProfiler::NewRenderBuffer, ts.elapsed(), rb);
|
startEntry(QRhiProfiler::NewRenderBuffer, ts.elapsed(), rb);
|
||||||
writeInt("type", type);
|
writeInt("type", type);
|
||||||
@ -416,7 +416,7 @@ void QRhiProfilerPrivate::newTexture(QRhiTexture *tex, bool owns, int mipCount,
|
|||||||
const QSize sz = tex->pixelSize();
|
const QSize sz = tex->pixelSize();
|
||||||
quint32 byteSize = rhiDWhenEnabled->approxByteSizeForTexture(format, sz, mipCount, layerCount);
|
quint32 byteSize = rhiDWhenEnabled->approxByteSizeForTexture(format, sz, mipCount, layerCount);
|
||||||
if (sampleCount > 1)
|
if (sampleCount > 1)
|
||||||
byteSize *= sampleCount;
|
byteSize *= uint(sampleCount);
|
||||||
|
|
||||||
startEntry(QRhiProfiler::NewTexture, ts.elapsed(), tex);
|
startEntry(QRhiProfiler::NewTexture, ts.elapsed(), tex);
|
||||||
writeInt("width", sz.width());
|
writeInt("width", sz.width());
|
||||||
@ -467,7 +467,7 @@ void QRhiProfilerPrivate::resizeSwapChain(QRhiSwapChain *sc, int bufferCount, in
|
|||||||
|
|
||||||
const QSize sz = sc->currentPixelSize();
|
const QSize sz = sc->currentPixelSize();
|
||||||
quint32 byteSize = rhiDWhenEnabled->approxByteSizeForTexture(QRhiTexture::BGRA8, sz, 1, 1);
|
quint32 byteSize = rhiDWhenEnabled->approxByteSizeForTexture(QRhiTexture::BGRA8, sz, 1, 1);
|
||||||
byteSize = byteSize * bufferCount + byteSize * msaaBufferCount * sampleCount;
|
byteSize = byteSize * uint(bufferCount) + byteSize * uint(msaaBufferCount) * uint(sampleCount);
|
||||||
|
|
||||||
startEntry(QRhiProfiler::ResizeSwapChain, ts.elapsed(), sc);
|
startEntry(QRhiProfiler::ResizeSwapChain, ts.elapsed(), sc);
|
||||||
writeInt("width", sz.width());
|
writeInt("width", sz.width());
|
||||||
@ -569,7 +569,7 @@ void QRhiProfilerPrivate::swapChainFrameGpuTime(QRhiSwapChain *sc, float gpuTime
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QRhiProfilerPrivate::newReadbackBuffer(quint64 id, QRhiResource *src, quint32 size)
|
void QRhiProfilerPrivate::newReadbackBuffer(qint64 id, QRhiResource *src, quint32 size)
|
||||||
{
|
{
|
||||||
if (!outputDevice)
|
if (!outputDevice)
|
||||||
return;
|
return;
|
||||||
@ -580,7 +580,7 @@ void QRhiProfilerPrivate::newReadbackBuffer(quint64 id, QRhiResource *src, quint
|
|||||||
endEntry();
|
endEntry();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QRhiProfilerPrivate::releaseReadbackBuffer(quint64 id)
|
void QRhiProfilerPrivate::releaseReadbackBuffer(qint64 id)
|
||||||
{
|
{
|
||||||
if (!outputDevice)
|
if (!outputDevice)
|
||||||
return;
|
return;
|
||||||
@ -590,7 +590,7 @@ void QRhiProfilerPrivate::releaseReadbackBuffer(quint64 id)
|
|||||||
endEntry();
|
endEntry();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QRhiProfilerPrivate::vmemStat(int realAllocCount, int subAllocCount, quint32 totalSize, quint32 unusedSize)
|
void QRhiProfilerPrivate::vmemStat(uint realAllocCount, uint subAllocCount, quint32 totalSize, quint32 unusedSize)
|
||||||
{
|
{
|
||||||
if (!outputDevice)
|
if (!outputDevice)
|
||||||
return;
|
return;
|
||||||
|
@ -79,10 +79,10 @@ public:
|
|||||||
void endSwapChainFrame(QRhiSwapChain *sc, int frameCount);
|
void endSwapChainFrame(QRhiSwapChain *sc, int frameCount);
|
||||||
void swapChainFrameGpuTime(QRhiSwapChain *sc, float gpuTimeMs);
|
void swapChainFrameGpuTime(QRhiSwapChain *sc, float gpuTimeMs);
|
||||||
|
|
||||||
void newReadbackBuffer(quint64 id, QRhiResource *src, quint32 size);
|
void newReadbackBuffer(qint64 id, QRhiResource *src, quint32 size);
|
||||||
void releaseReadbackBuffer(quint64 id);
|
void releaseReadbackBuffer(qint64 id);
|
||||||
|
|
||||||
void vmemStat(int realAllocCount, int subAllocCount, quint32 totalSize, quint32 unusedSize);
|
void vmemStat(uint realAllocCount, uint subAllocCount, quint32 totalSize, quint32 unusedSize);
|
||||||
|
|
||||||
void startEntry(QRhiProfiler::StreamOp op, qint64 timestamp, QRhiResource *res);
|
void startEntry(QRhiProfiler::StreamOp op, qint64 timestamp, QRhiResource *res);
|
||||||
void writeInt(const char *key, qint64 v);
|
void writeInt(const char *key, qint64 v);
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -711,8 +711,9 @@ public:
|
|||||||
int resourceLimit(QRhi::ResourceLimit limit) const override;
|
int resourceLimit(QRhi::ResourceLimit limit) const override;
|
||||||
const QRhiNativeHandles *nativeHandles() override;
|
const QRhiNativeHandles *nativeHandles() override;
|
||||||
void sendVMemStatsToProfiler() override;
|
void sendVMemStatsToProfiler() override;
|
||||||
void makeThreadLocalNativeContextCurrent() override;
|
bool makeThreadLocalNativeContextCurrent() override;
|
||||||
void releaseCachedResources() override;
|
void releaseCachedResources() override;
|
||||||
|
bool isDeviceLost() const override;
|
||||||
|
|
||||||
VkResult createDescriptorPool(VkDescriptorPool *pool);
|
VkResult createDescriptorPool(VkDescriptorPool *pool);
|
||||||
bool allocateDescriptorSet(VkDescriptorSetAllocateInfo *allocInfo, VkDescriptorSet *result, int *resultPoolIndex);
|
bool allocateDescriptorSet(VkDescriptorSetAllocateInfo *allocInfo, VkDescriptorSet *result, int *resultPoolIndex);
|
||||||
@ -804,6 +805,7 @@ public:
|
|||||||
VkDeviceSize ubufAlign;
|
VkDeviceSize ubufAlign;
|
||||||
VkDeviceSize texbufAlign;
|
VkDeviceSize texbufAlign;
|
||||||
bool hasWideLines = false;
|
bool hasWideLines = false;
|
||||||
|
bool deviceLost = false;
|
||||||
|
|
||||||
bool debugMarkersAvailable = false;
|
bool debugMarkersAvailable = false;
|
||||||
bool vertexAttribDivisorAvailable = false;
|
bool vertexAttribDivisorAvailable = false;
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user