Производительность графики Qt на ARM с плавающей запятой?

Я хотел бы создать интерфейс Qt, похожий на приборную панель автомобиля (датчики, циферблаты, ручки и т. Д.). Мое устройство оснащено ЖК-дисплеем с разрешением 800x480, работающим на SoC imx287 ARM (armv5te без аппаратного плавающего режима или графического процессора).

У меня проблема в том, что он очень медленный. Один датчик (фоновое изображение в формате PNG с вращающимся изображением циферблата в формате PNG), отрисовываемый со скоростью 20 кадров в секунду, потребляет ~ 20% процессорного времени. Добавление одной отображаемой текстовой строки увеличивает использование ЦП до 40%.

Я использую QGraphicsScene, в котором я использую много вычислений с плавающей запятой ... проблема, поскольку мой SoC не имеет аппаратной способности плавать.

Есть ли альтернативы QGraphicsScene, которые мне подошли бы?

Это то, что я сейчас делаю:

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);

bg.load("rpm.png");
needle.load("needle.png");

scene = new QGraphicsScene(this);
scene->setSceneRect(0,0, 800,480);

scene->addPixmap(bg);

needleItem = scene->addPixmap(needle);
needleItem->setPos(400-4,17);

textItem = scene->addText(tr(""), QFont("utsaah", 50, QFont::Bold, true));
textItem->setDefaultTextColor(QColor(255,255,255));
textItem->setPos(430, 360);

ui->graphicsView->setScene(scene);

thread = new UpdateDialsThread(this);
connect(thread, SIGNAL(updateDials()), this, SLOT(updateDials()));
thread->start();
}

void MainWindow::updateDials(void)
{
static int deg = 180;

deg += 1;
if (deg > 180+270)
    deg = 180;

QTransform trans;
trans.translate(needleItem->boundingRect().width()/2, needleItem->boundingRect().height());
trans.rotate(deg, Qt::ZAxis);
trans.translate(-needleItem->boundingRect().width()/2, -needleItem->boundingRect().height());
needleItem->setTransform(trans);

textItem->setPlainText(tr("%1").arg(deg*10, 4, 'f', 0));
}

Заранее спасибо!


person thecoder    schedule 24.04.2014    source источник
comment
Я использую Qt 4.8.5 в специально созданном дистрибутиве (используя buildroot). Я пытался сбросить битовую глубину с помощью этого, но, похоже, это не имеет никакого эффекта. Я не уверен, как проверить битовую глубину в приложении, чтобы проверить, действительно ли работают параметры. QWS_DISPLAY=LinuxFb:/dev/fb0:depth=16 QWS_DEPTH=16 ./test3 -qws   -  person thecoder    schedule 25.04.2014
comment
Я собирал всю ОС с -O3, но сейчас попробую -Os, чтобы увидеть, в чем разница. Я уже компилировал все с помощью -march=armv5te -mtune=arm926ej-s. В Qt были включены глубины 1, 16, 24, 32, но я попробую включить только 1 и 16. Это плата, которую я использую: crystalfontz.com/product/CFA921TS . Спасибо за помощь.   -  person thecoder    schedule 26.04.2014
comment
blit_setup(): Глубина экрана 32 не поддерживается! Устройство linuxfb поддерживает только 32-битную версию.   -  person thecoder    schedule 27.04.2014
comment
Хорошо, обновление. Я попытался собрать все с помощью -Os, тестовое приложение (код, как указано выше) использует ЦП примерно на 4% больше, чем -O3. Добавление -no-armfpa, похоже, ничего не изменило. Теперь я перешел на использование GCC 4.8.1 вместо 4.6.x, что уменьшило использование ЦП примерно на 8%. Если у вас, ребята, нет больше предложений, похоже, это настолько хорошо, насколько это возможно.   -  person thecoder    schedule 28.04.2014
comment
Конечно, вы можете заставить драйвер поддерживать 16-битные буферы кадров (или даже меньше); IMX просто устанавливает нулевую линию low/unused. Это уменьшит пропускную способность памяти наполовину, что является основной проблемой блиттера. У вас есть исходники линукса? Какая версия? Если вы не можете изменить Linux, то это лучшее, на что вы можете надеяться.   -  person artless noise    schedule 28.04.2014
comment
Хорошо, спасибо за предложение. Я начну взламывать код драйвера ядра linuxfb. Будет интересно посмотреть, насколько это изменит ситуацию. Я немного удивлен, что Qt не имеет возможности рендеринга во внутренний 16-битный буфер, а затем записи в 32-битный буфер linuxfb. Спасибо еще раз! Я обновлю, когда внесу изменения и проведу некоторое тестирование.   -  person thecoder    schedule 29.04.2014
comment
Это должно быть так же просто, как обновить .bpp и .pcr. Замените .bpp = 32 и .pcr = 0xF0D00080|END_SEL на .bpp = 16 и .pcr = 0xF0D00080 (хорошо для iMx25, использующего платформенное устройство). Т.е. драйвер это поддерживает, нужно просто отправить какие-то конфигурационные данные. Возможно, вам придется взглянуть на таблицу данных iMx28 для значения .pcr.   -  person artless noise    schedule 29.04.2014
comment
Кажется, это было проще. Мне просто нужно было изменить битовую глубину в исходном файле дерева драйверов. Это помогло, снизив загрузку процессора еще на 8%. Таким образом, выполнение кода в OP теперь использует ~ 22% процессорного времени. Я думаю, что на данный момент этого достаточно... я закончу создание моего приложения Qt и вернусь к этому позже, если возникнут проблемы. Спасибо еще раз!   -  person thecoder    schedule 01.05.2014


Ответы (2)


Я рекомендую использовать QML вместо QGraphicsView. Вы можете создавать собственные датчики с привлекательной анимацией с хорошей производительностью. Вы также можете иметь пружинный и демпфирующий эффекты. Вы можете ознакомиться с примером управления набором номера. .

person Nejat    schedule 24.04.2014
comment
Пример Dial Control использует ~ 60% загрузки ЦП при перемещении ползунка. Не вариант. - person thecoder; 24.04.2014

В итоге я перешел на Allegro 4.

Он гораздо лучше подходит для этой задачи. Намного легче и поддерживает математику с фиксированной точкой.

person thecoder    schedule 14.07.2014