Я пытаюсь создать компонент QML, который бы выводил в реальном времени и масштабировал изображение 2000x2000 при 60 кадрах в секунду.
Я закончил с пользовательским QQuickItem, так как QQuickImageProvider, похоже, предназначен для других целей, а QQuickPaintedItem не дал мне желаемой производительности.
Итак, у меня есть:
MyQuickItem.cpp
MyQuickItem::MyQuickItem(QQuickItem *parent)
: QQuickItem(parent)
{
setFlag(ItemHasContents, true);
}
void MyQuickItem::setImage(QImage image)
{
if (!image.isNull()) {
currentImg = image;
update();
}
}
QSGNode* MyQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data)
{
QSGImageNode * node;
if (!oldNode) {
node = window()->createImageNode();
oldNode = node;
} else {
node = static_cast<QSGImageNode *>(oldNode);
}
QSGTexture *texture = window()->createTextureFromImage(currentImg);
node->setRect(boundingRect());
node->setSourceRect(QRectF(QPointF(0.0, 0.0), texture->textureSize()));
node->setTexture(texture);
node->setOwnsTexture(true);
return node;
}
Регистрация этого как
qmlRegisterType<MyQuickItem>("MyItem", 1, 0, "MyItem");
QQmlComponent* component = new QQmlComponent(engine, ":/test.qml");
MyQuickItem* myItem = quickItem->findChild<MyQuickItem*>("myItem");
if (myItem ) {
connect(this, &ImageGenerator::newFrame, radarItem, &MyQuickItem::setImage);
}
и создание в QML:
import MyItem1.0
import QtQuick 2.3
Item {
MyItem{
id: myImage
objectName: "myItem"
visible: true
anchors.fill: parent
anchors.centerIn: parent
}
Rectangle {
id: boundingRect
border.color: "blue"
border.width: 3
color: "transparent"
anchors.fill: parent
}
anchors.fill: parent
}
У меня это работает. ImageGenerator создает 2000x2000 QImage и отправляет его в MyItem, который является MyQuickItem.
И это все еще очень медленно. Он потребляет около 30% от i5-4460 и «замораживает» другие компоненты пользовательского интерфейса.
Исследование:
Изменение QSGImageNode на QSGRectangleNode со сплошным цветом, но все еще выполняется
QSGTexture *texture = window()->createTextureFromImage(currentImg);
уменьшить загрузку процессора до 1-3%.
Но как только я добавлю
texture->bind();
снова 30% процессорного времени.
Итак, одна проблема в том, что изображение 2000x2000 слишком медленно для загрузки в графический процессор.
С другой стороны
QSGTexture *texture = window()->createTextureFromImage(currentImg.scaled(boundingRect().size().toSize()));
без и с bind () дает те же 30% ЦП.
другая проблема в том, что масштабирование 2000x2000 для соответствия размеру компонента QML на ЦП слишком медленное.
Есть ли возможность уменьшить это отвратительное потребление ресурсов процессора?
P.S. Я не могу сгенерировать QImage с другим размером, но могу использовать указатель для буфера, чтобы сгенерировать изображение.
Первоначально этот генератор изображений использовался в QWidget, и таких проблем не было: QImage был создан 2000x2000 и установлен в качестве изображения для QWidget. Такое же потребление ресурсов процессора составило 2-3%.