имею я плату blueshark
На ней стоит модифицированный Angstrom (вырезано все лишнее).
Все это подключено к монитору Nec с разрешением 1024x600.
Задача этой платы - рисовать статическую картинку и стрелочки на ней (приборная панель).
Данные с датчиков валят с частотой 200 Гц. Я решил, что для отображения 25 Гц достаточно, чтобы не было видимых тормозов. Накидал небольшую тестовую программку, которая просто двигает стрелки и обновляет экран с частотой 25 Гц. На десктопе все прекрасно - 25. Однако, запустив на встраиваемой системе (драйвер linuxFb), получил значение 15 кадров/сек (Программа тупо считает за секунду, сколько раз она успела прорисоваться).
В общем, подскажите, в какую сторону мне дальше двигать.
1. Я рисую при помощи QPainter на главном окне. Прочитал, что QGraphicsScene оптимизирована под динамическую 2D. Однако она использует для отрисовки QPainter (как я понял). Имеет ли смысл переписывать программу? Даст ли использование QGraphicsScene какой либо прирост производительности?
2. Как мне оптимизировать программу? Может быть есть иные, более скоростные способы отрисовки?
В общем, буду рад любому дельному совету...
файл main.cpp
#include <QtGui/QApplication>
#include "ag_window.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ag_window w;
w.show();
return a.exec();
}
файл ag_window.cpp
#include "ag_window.h"
ag_window::ag_window(QWidget *parent) :
QWidget(parent)
{
painter=new QPainter();
this->setFixedSize(1024,600);
this->showFullScreen();
inc=0;
fps=0;
frame=0;
settings=new QSettings("settings.ini",QSettings::IniFormat);
settings->sync();
setFile=new QFile("settings.ini");
if(!setFile->exists() || settings->status()!=QSettings::NoError)
{
settings->beginGroup("Colors");
settings->setValue("hourColor","#1010ff");
settings->setValue("barColor","#1010ff");
settings->setValue("speedColor","#1010ff");
settings->setValue("altitudeColor","#1010ff");
settings->setValue("clockColor","#1010ff");
settings->endGroup();
settings->beginGroup("AliasCoef");
settings->setValue("oilTemp",0.1);
settings->setValue("oilPress",0.1);
settings->setValue("volt",0.1);
settings->setValue("fuel",0.1);
settings->setValue("altitude",0.1);
settings->setValue("speed",0.1);
settings->setValue("eTemp1",0.1);
settings->setValue("eTemp2",0.1);
settings->setValue("eTemp3",0.1);
settings->setValue("eTemp4",0.1);
settings->setValue("hTemp1",0.1);
settings->setValue("hTemp2",0.1);
settings->setValue("hTemp3",0.1);
settings->setValue("hTemp4",0.1);
settings->endGroup();
settings->sync();
}
longArrow=new QPixmap(":/image/img/Long_Arrow.png");
shortArrow=new QPixmap(":/image/img/Short_Arrow.png");
staticMap=new QPixmap(":/image/img/static-std.png");
line=new QPixmap(":/image/img/line.png");
arrows=new ag_arrow*[6];
lines=new ag_line*[8];
refreshTimer=new QTimer();
connect(refreshTimer,SIGNAL(timeout()),SLOT(refresh()));
refreshTimer->start(40);
fpsTimer=new QTimer();
connect(fpsTimer,SIGNAL(timeout()),SLOT(fpsup()));
fpsTimer->start(1000);
oilTemp=new ag_arrow(this,longArrow,10,QPoint(15,379),0,-90,0,140,0);
oilPress=new ag_arrow(this,longArrow,10,QPoint(18,545),0,-90,0,10,0);
volt=new ag_arrow(this,longArrow,10,QPoint(1009,379),-180,-90,10,17,10);
fuel=new ag_arrow(this,longArrow,10,QPoint(1006,545),-180,-90,0,1,0);
altitude=new ag_arrow(this,shortArrow,250,QPoint(512,300),50,-50,0,1000,0);
speed=new ag_arrow(this,shortArrow,250,QPoint(512,300),-230,-130,0,200,0);
arrows[0]=oilTemp;
arrows[1]=oilPress;
arrows[2]=volt;
arrows[3]=fuel;
arrows[4]=altitude;
arrows[5]=speed;
eTemp1=new ag_line(this,line,QPoint(28,54),26,160,250,1200,0);
eTemp2=new ag_line(this,line,QPoint(56,54),26,160,250,1200,0);
eTemp3=new ag_line(this,line,QPoint(84,54),26,160,250,1200,0);
eTemp4=new ag_line(this,line,QPoint(112,54),26,160,250,1200,0);
hTemp1=new ag_line(this,line,QPoint(886,54),26,160,60,120,0);
hTemp2=new ag_line(this,line,QPoint(914,54),26,160,60,120,0);
hTemp3=new ag_line(this,line,QPoint(942,54),26,160,60,120,0);
hTemp4=new ag_line(this,line,QPoint(970,54),26,160,60,120,0);
lines[0]=eTemp1;
lines[1]=eTemp2;
lines[2]=eTemp3;
lines[3]=eTemp4;
lines[4]=hTemp1;
lines[5]=hTemp2;
lines[6]=hTemp3;
lines[7]=hTemp4;
settings->beginGroup("AliasCoef");
oilTemp->expCoef=settings->value("oilTemp",0.1).toFloat();
settings->endGroup();
settings->beginGroup("Colors");
hourLCD=new QLCDNumber(3,this);
hourLCD->setGeometry(QRect(150,535,100,65));
hourLCD->setFrameStyle(0);
hourLCD->setSegmentStyle(QLCDNumber::Filled);
hourLCD->display(250);
QPalette tempPalette=hourLCD->palette();
tempPalette.setColor(QPalette::Normal,QPalette::WindowText,QColor(settings->value("hourColor","#000000").toString()));
hourLCD->setPalette(tempPalette);
hourLCD->show();
barLCD=new QLCDNumber(3,this);
barLCD->setGeometry(QRect(773,535,100,65));
barLCD->setFrameStyle(0);
barLCD->setSegmentStyle(QLCDNumber::Filled);
barLCD->display(760);
tempPalette=barLCD->palette();
tempPalette.setColor(QPalette::Normal,QPalette::WindowText,QColor(settings->value("barColor","#000000").toString()));
barLCD->setPalette(tempPalette);
barLCD->show();
speedLCD=new QLCDNumber(3,this);
speedLCD->setGeometry(QRect(150,0,100,65));
speedLCD->setFrameStyle(0);
speedLCD->setSegmentStyle(QLCDNumber::Filled);
speedLCD->display(0);
tempPalette=speedLCD->palette();
tempPalette.setColor(QPalette::Normal,QPalette::WindowText,QColor(settings->value("speedColor","#000000").toString()));
speedLCD->setPalette(tempPalette);
speedLCD->show();
altitudeLCD=new QLCDNumber(3,this);
altitudeLCD->setGeometry(QRect(773,0,100,65));
altitudeLCD->setFrameStyle(0);
altitudeLCD->setSegmentStyle(QLCDNumber::Filled);
altitudeLCD->display(0);
tempPalette=altitudeLCD->palette();
tempPalette.setColor(QPalette::Normal,QPalette::WindowText,QColor(settings->value("altitudeColor","#000000").toString()));
altitudeLCD->setPalette(tempPalette);
altitudeLCD->show();
clockLCD=new QLCDNumber(8,this);
clockLCD->setGeometry(QRect(362,545,300,55));
clockLCD->setFrameStyle(0);
clockLCD->setSegmentStyle(QLCDNumber::Filled);
clockLCD->display("23:25:40");
tempPalette=clockLCD->palette();
tempPalette.setColor(QPalette::Normal,QPalette::WindowText,QColor(settings->value("clockColor","#000000").toString()));
clockLCD->setPalette(tempPalette);
clockLCD->show();
settings->endGroup();
speedLCD->connect(speed,SIGNAL(changed(double)),SLOT(display(double)));
altitudeLCD->connect(altitude,SIGNAL(changed(double)),SLOT(display(double)));
settings->sync();
installEventFilter(this);
}
bool ag_window::eventFilter(QObject *o, QEvent *e)
{
if (o==this && e->type()== QEvent::Paint)
{
painter->begin(this);
painter->setRenderHint(QPainter::SmoothPixmapTransform,true);
painter->drawPixmap(0,0,*staticMap);
painter->drawText(QPoint(512,300), QString("FPS - %1").arg(fps));
for (quint16 i=0;i<6;i++) arrows[i]->repaint(painter);
for (quint16 i=0;i<8;i++) lines[i]->repaint(painter);
painter->end();
frame++;
return true;
}
return false;
}
void ag_window::fpsup(void)
{
fps=frame;
frame=0;
}
void ag_window::refresh(void)
{
inc+=10;
if (inc>140) inc=0;
oilTemp->update_value(inc);
oilPress->update_value(inc/10);
volt->update_value(inc/5);
fuel->update_value(inc/100);
speed->update_value(inc*2);
altitude->update_value(inc*7.14286);
eTemp1->update_value(inc*8.57);
eTemp2->update_value(inc*8.57);
eTemp3->update_value(inc*8.57);
eTemp4->update_value(inc*8.57);
hTemp1->update_value(inc/2+60);
hTemp2->update_value(inc/2+60);
hTemp3->update_value(inc/2+60);
hTemp4->update_value(inc/2+60);
this->update();
}
Файл ag_line.cpp
#include "ag_line.h"
ag_line::ag_line(QObject *parent,QPixmap *aPixmap,QPoint aPosition, quint16 aWidth, quint16 aHeight, float aMin, float aMax, float aValue ) :
QObject(parent)
{
position=aPosition;
height=aHeight;
width=aWidth;
min=aMin;
max=aMax;
value=aValue;
expCoef=0.1;
pixmap=aPixmap;
coef=height/(max-min);
clip.setRect(0,0,width,height);
update_value(value);
}
void ag_line::update_value(float aValue)
{
if (aValue<min) aValue=min;
if (aValue>max) aValue=max;
value=value*(1-expCoef)+aValue*expCoef;
clip.setRect(0,(int)(height-(value-min)*coef),width,(int)((value-min)*coef+1));
emit changed (value);
}
void ag_line::repaint(QPainter *painter)
{
painter->save();
painter->translate(position);
painter->setClipRect(clip);
painter->drawPixmap(QPoint(0,0),*pixmap);
painter->restore();
}
файл ag_arrow.cpp
#include "ag_arrow.h"
ag_arrow::ag_arrow(QObject *parent,QPixmap *aPixmap, quint16 aR, QPoint aCenter, float aAngleMin, float aAngleMax, float aMin, float aMax, float aValue) :
QObject(parent)
{
r=aR;
pixmap=aPixmap;
origin.setX(0);
origin.setY(-pixmap->height()/2);
center=aCenter;
min=aMin;
max=aMax;
minAngle=aAngleMin;
maxAngle=aAngleMax;
value=aValue;
expCoef=0.1;
coef=(maxAngle-minAngle)/(max-min);
update_value(value);
}
void ag_arrow::update_value(float aValue)
{
if (aValue<min) aValue=min;
if (aValue>max) aValue=max;
value=value*(1-expCoef)+aValue*expCoef;
angle=minAngle+(value-min)*coef;
offset.setX((int)(center.x()+r*cos((angle)*DEG2RAD)));
offset.setY((int)(center.y()+r*sin((angle)*DEG2RAD)));
emit changed (value);
}
void ag_arrow::repaint(QPainter *painter)
{
painter->save();
painter->translate(offset);
painter->rotate(angle);
painter->drawPixmap(origin,*pixmap);
painter->restore();
}