3

I would like to create a car dashboard-like Qt interface (gauges, dials, knobs, etc). My device has a 800x480 LCD powered by a imx287 ARM SoC (armv5te with no hardware float, or GPU).

The problem im having is its very slow. A single gauge (background PNG image, with rotating PNG dial image) drawn at 20fps uses a ~20% CPU time. Adding a single rendered text string increases that up to 40% CPU use.

Im using QGraphicsScene which i uses a lot of floating point calcs... a problem since my SoC has no hardware float ability.

Are there any alternatives to QGraphicsScene that would work well for me?

This is what im currently doing:

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));
}

Thanks in advance!

thecoder
  • 55
  • 8
  • Im using Qt 4.8.5 on a custom built distro (using buildroot). Ive tried dropping bitdepth using this, but it doesnt seem to have any effect. Im not sure how to test bit depth in the app to check the options are actually working. QWS_DISPLAY=LinuxFb:/dev/fb0:depth=16 QWS_DEPTH=16 ./test3 -qws – thecoder Apr 25 '14 at 05:22
  • I was building the whole OS with -O3, but ill try -Os now to see what the difference is. I have been compiling everything with -march=armv5te -mtune=arm926ej-s already. Qt did have depths 1,16,24,32 enabled, but ill try only enabling 1 & 16. This is the board im using: http://www.crystalfontz.com/product/CFA921TS . Thanks for the help. – thecoder Apr 26 '14 at 05:26
  • 1
    blit_setup(): Screen depth 32 not supported! The linuxfb device only supports 32bit. – thecoder Apr 27 '14 at 04:27
  • Ok, an update. I tried building everything with -Os, the test app (code as above) uses about 4% more CPU use than -O3. Adding -no-armfpa doesnt seem to have made any difference. I have now changed to using GCC 4.8.1 instead of 4.6.x which has reduced CPU use by about 8%. Unless you guys have any more suggestions, it looks like this is as good as it'll get. – thecoder Apr 28 '14 at 05:56
  • You can certainly make the driver support 16bit frame buffers (or even less); the IMX just sets the low/unused line to zeros. This will 1/2 the memory bandwidth, which is the major issue with the blitter. Do you have the Linux source? Which version is it? If you can not change Linux, then this is the best you can hope for. – artless noise Apr 28 '14 at 16:18
  • Ok, thanks for the suggestion. Ill start hacking away at the kernel linuxfb driver code. It'll be interesting to see how much of a difference it makes. Im a little surprised Qt doesnt have the option of rendering to an internal 16bit buffer, then writing to the 32bit linuxfb buffer. Thanks again! Ill update when i have made teh changes & done some testing. – thecoder Apr 29 '14 at 18:12
  • It should be as easy as updating `.bpp` and `.pcr`. Change `.bpp = 32` and `.pcr = 0xF0D00080|END_SEL` to `.bpp = 16` and `.pcr = 0xF0D00080` (well for the iMx25 using a *platform device*). Ie, the driver supports it, you just need to send some *configuration* data. You might have to look at the iMx28 data sheet for the `.pcr` value. – artless noise Apr 29 '14 at 18:29
  • Seems it was easier than that. I just had to modify the bitdepth in the driver tree source file. It has helped, dropping cpu use by another 8%. So running the code in the OP now uses ~22% cpu time. That will do for now i think... ill finish off making my Qt app, and come back to this if its a problem later. Thanks again! – thecoder May 01 '14 at 15:57

2 Answers2

1

I recommend to Use QML instead of QGraphicsView. You can create custom gauges with eye-catching animations with good performance. You can also have spring and damping effects. You can take a look at Dial Control Example.

Nejat
  • 31,784
  • 12
  • 106
  • 138
0

I ended up moving to Allegro 4.

Its much better suited to this task. A lot lighter, and supports fixed-point math.

thecoder
  • 55
  • 8