Russian Qt Forum
Ноябрь 22, 2024, 17:00 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Отрисовка 2D графики на embedded linux  (Прочитано 6913 раз)
RattleSnake
Гость
« : Март 26, 2012, 11:57 »

В общем ситуация такая:

имею я плату blueshark 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();
}

Записан
Bepec
Гость
« Ответ #1 : Март 26, 2012, 12:04 »

Почитал. Посмотрел. Посмотрел вокруг на наличие платы. Не нашёл. Бросил дело. :/
Записан
RattleSnake
Гость
« Ответ #2 : Март 26, 2012, 12:10 »

А если чисто гипотетически, так сказать без платы проанализировать? Я с Qt знаком очень мало, я просто уверен, что накосячил много:)
Записан
Bepec
Гость
« Ответ #3 : Март 26, 2012, 12:22 »

У меня при запуске выдаёт 18 фпс и жрёт одно ядро(50% проца) Веселый
Записан
_OLEGator_
Гость
« Ответ #4 : Март 26, 2012, 14:39 »

Надо выяснить, что именно тормозит, найти кусок кода, который дольше необходимого выполняется - его и оптимизировать.
Возможно тормозит из-за этого: QPainter::SmoothPixmapTransform
Записан
Patrin Andrey
Гость
« Ответ #5 : Март 30, 2012, 15:03 »

QGraphicsScene однозначно стоит попробывать.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.07 секунд. Запросов: 20.