c++ - Qt design and performance issue -


i having troubles while designing c++ qt application. among other things, application displays beams (or rays) of lasers (each laser composed around 700 segments starting same position , spaced constant angle, , small circle @ other end of segment materializing end point). here drafting of 1 laser found on internet . of time have display 12 lasers (so 12*700 segments), @ 30 frames per second. first implementation works, takes huge amount of cpu (>12%) , gui lags lot.

what did implementation quite simple: have lasermodel class, filled thread receiving tcp beacons; mainwindow class qgraphicsscene* _scene; , laserview class, instances added scene. signal @ 30fps triggers passage of datas model view using setdata() method.

i did performance analysis , seems 80% of work of gui (there way more displaying these lasers) done drawline(/*…*/) methods.

i sure there more elegant , efficient way that.

  • first setdata(/*…*/) method seems quite ugly me. know should emit signal (like laserhaschanged(const lasermodel&)) model , catch in view (with slot onnewdata(const lasermodel&)) performance point of view seems worse (but looks better coupling point of view, because in future display property tree configuration of lasers(so view of same model)).

  • more important not quite sure drawline(const qline& line) does, part of code should “render” line, not recreate it.

so question is: how can drastically improve performances of rendering? drawline part of paint() method?

here relevant code:

class laserview : public qgraphicsitem {     /* c-tor, d-tor, members... */     std::vector<beam> _beams;     qrectf _boundingrect;      void setdata(const sim::pose& pose, const std::vector<beam>& beams, const qrectf& boundingrect, const bool& showmaxranges) {         /*...*/         _beams = beams;         _boundingrect = boundingrect;     }     void paint(qpainter *painter, const qstyleoptiongraphicsitem *option, qwidget *) {         painter->setpen(_color);         // display beams stopped obstacle         if (!_showmaxranges) {             (unsigned int = 0 ; < _beams.size() -1 ; i++) {                 if (!_beams[i].endpointtype == laserbeamendpointtype::max_range) {                     _beams[i]._line.setline(_pose.x, _pose.y, _beams[i]._mapendpose.x(), _beams[i]._mapendpose.y());                     painter->drawline(_beams[i]._line);                 }             }         }         // display beams         else {             (unsigned int = 0 ; < _beams.size() -1 ; i++) {                 _beams[i]._line.setline(_pose.x, _pose.y, _beams[i]._mapendpose.x(), _beams[i]._mapendpose.y());                 painter->drawline(_beams[i]._line);             }         }         // draw small circle visualize end points of beams when stop against obstacle         (unsigned int = 0; < _beams.size() - 1 ; i++) {             // draw end point in blue if obstacle reflective             if (_beams[i].endpointtype == laserbeamendpointtype::reflective_object) {                 painter->setbrush(refletive_end_point_color);                 painter->drawellipse(_beams[i]._mapendpose, end_point_size, end_point_size);                             }             // draw end point in red if obstacle not reflective             else if (_beams[i].endpointtype == laserbeamendpointtype::not_reflective_object) {                 painter->setbrush(not_refletive_end_point_color);                 painter->drawellipse(_beams[i]._mapendpose, end_point_size, end_point_size);                                         }     } } 

}

you drawing 1 line @ time, 1 ellipse @ time, switching between brushes in process. there significant overhead these operations (at least qt4). can better aggregating these calls 3 drawing calls.

you have

std::vector<qlinef> lines; std::vector<qrectf> ellipse_refl_rects; std::vector<qrectf> ellipse_non_refl_rects; 

rather drawing line add lines collection. same ellipses. @ end have

if(!lines.isempty()) {     painter->drawlines(&lines[0], lines.size()); }  if(!ellipse_refl_rects.isempty()) {     painter->setbrush(refletive_end_point_color);     painter->drawellipses(&ellipse_refl_rects[0], ellipse_refl_rects.size()); }  if(!ellipse_non_refl_rects.isempty()) {     painter->setbrush(not_refletive_end_point_color);     painter->drawellipses(&ellipse_non_refl_rects[0], ellipse_non_refl_rects.size()); } 

Comments

Popular posts from this blog

c++ - Delete matches in OpenCV (Keypoints and descriptors) -

java - Could not locate OpenAL library -

sorting - opencl Bitonic sort with 64 bits keys -