Название: Отрисовка 2D графики на embedded linux
Отправлено: RattleSnake от Март 26, 2012, 11:57
В общем ситуация такая: имею я плату blueshark http://mentorel.ru/index.php/products/som/blueshark-omap3 (http://mentorel.ru/index.php/products/som/blueshark-omap3) На ней стоит модифицированный 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(); }
Название: Re: Отрисовка 2D графики на embedded linux
Отправлено: Bepec от Март 26, 2012, 12:04
Почитал. Посмотрел. Посмотрел вокруг на наличие платы. Не нашёл. Бросил дело. :/
Название: Re: Отрисовка 2D графики на embedded linux
Отправлено: RattleSnake от Март 26, 2012, 12:10
А если чисто гипотетически, так сказать без платы проанализировать? Я с Qt знаком очень мало, я просто уверен, что накосячил много:)
Название: Re: Отрисовка 2D графики на embedded linux
Отправлено: Bepec от Март 26, 2012, 12:22
У меня при запуске выдаёт 18 фпс и жрёт одно ядро(50% проца) :D
Название: Re: Отрисовка 2D графики на embedded linux
Отправлено: _OLEGator_ от Март 26, 2012, 14:39
Надо выяснить, что именно тормозит, найти кусок кода, который дольше необходимого выполняется - его и оптимизировать. Возможно тормозит из-за этого: QPainter::SmoothPixmapTransform
Название: Re: Отрисовка 2D графики на embedded linux
Отправлено: Patrin Andrey от Март 30, 2012, 15:03
QGraphicsScene однозначно стоит попробывать.
|