From 8a261384431c4523cb1e49d88b232cfeca858ecf Mon Sep 17 00:00:00 2001 From: DreamSourceLab Date: Tue, 24 May 2016 10:04:07 +0800 Subject: [PATCH] Improve performance of protocol decoder --- DSView/main.cpp | 3 +- DSView/pv/data/decode/row.cpp | 4 +- DSView/pv/data/decoderstack.cpp | 63 +++++++++++++++--- DSView/pv/data/decoderstack.h | 14 ++-- DSView/pv/data/logicsnapshot.cpp | 20 +++--- DSView/pv/data/snapshot.cpp | 2 + DSView/pv/dock/dsotriggerdock.cpp | 8 +-- DSView/pv/dock/measuredock.cpp | 8 +-- DSView/pv/dock/searchdock.cpp | 8 +-- DSView/pv/dock/triggerdock.cpp | 8 +-- DSView/pv/mainwindow.cpp | 2 +- DSView/pv/view/decodetrace.cpp | 103 ++++++++++++++++++++---------- DSView/pv/view/header.cpp | 2 +- DSView/pv/view/logicsignal.cpp | 2 + DSView/pv/view/ruler.cpp | 2 +- DSView/pv/view/viewport.cpp | 2 +- 16 files changed, 166 insertions(+), 85 deletions(-) diff --git a/DSView/main.cpp b/DSView/main.cpp index 60876c69..07bf54a7 100644 --- a/DSView/main.cpp +++ b/DSView/main.cpp @@ -35,6 +35,7 @@ #include #include +#include "dsapplication.h" #include "pv/devicemanager.h" #include "pv/mainwindow.h" @@ -59,7 +60,7 @@ int main(int argc, char *argv[]) struct sr_context *sr_ctx = NULL; const char *open_file = NULL; - QApplication a(argc, argv); + DSApplication a(argc, argv); // Language #ifdef LANGUAGE_ZH_CN diff --git a/DSView/pv/data/decode/row.cpp b/DSView/pv/data/decode/row.cpp index 06ae2987..46fb337f 100644 --- a/DSView/pv/data/decode/row.cpp +++ b/DSView/pv/data/decode/row.cpp @@ -68,8 +68,8 @@ const QString Row::title() const bool Row::operator<(const Row &other) const { - return (_decoder->name < other._decoder->name) || - (_decoder->name == other._decoder->name && _row->desc < other._row->desc); + return (_decoder < other._decoder) || + (_decoder == other._decoder && _row < other._row); } } // decode diff --git a/DSView/pv/data/decoderstack.cpp b/DSView/pv/data/decoderstack.cpp index beaf54a5..7615e0e2 100644 --- a/DSView/pv/data/decoderstack.cpp +++ b/DSView/pv/data/decoderstack.cpp @@ -17,12 +17,11 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include - #include #include #include +#include #include @@ -57,6 +56,7 @@ namespace data { const double DecoderStack::DecodeMargin = 1.0; const double DecoderStack::DecodeThreshold = 0.2; const int64_t DecoderStack::DecodeChunkLength = 4 * 1024; +//const int64_t DecoderStack::DecodeChunkLength = 1024 * 1024; const unsigned int DecoderStack::DecodeNotifyPeriod = 1024; mutex DecoderStack::_global_decode_mutex; @@ -443,11 +443,22 @@ void DecoderStack::decode_data( uint64_t notify_cnt = (decode_end - decode_start + 1)/100; const uint64_t chunk_sample_count = DecodeChunkLength / _snapshot->unit_size(); + srd_decoder_inst *logic_di = NULL; + // find the first level decoder instant + for (GSList *d = session->di_list; d; d = d->next) { + srd_decoder_inst *di = (srd_decoder_inst *)d->data; + srd_decoder *decoder = di->decoder; + const bool have_probes = (decoder->channels || decoder->opt_channels) != 0; + if (have_probes) { + logic_di = di; + break; + } + } - for (uint64_t i = decode_start; - !boost::this_thread::interruption_requested() && - i < decode_end && !_no_memory; - i += chunk_sample_count) + uint8_t chunk_type = 0; + uint64_t i = decode_start; + while(!boost::this_thread::interruption_requested() && + i < decode_end && !_no_memory) { //lock_guard decode_lock(_global_decode_mutex); @@ -455,22 +466,56 @@ void DecoderStack::decode_data( i + chunk_sample_count, decode_end); chunk = _snapshot->get_samples(i, chunk_end); - if (srd_session_send(session, i, chunk_end, chunk, + if (srd_session_send(session, chunk_type, i, chunk_end, chunk, (chunk_end - i) * unit_size, unit_size) != SRD_OK) { _error_message = tr("Decoder reported an error"); break; } + if (logic_di && logic_di->logic_mask != 0) { + uint64_t cur_pos = logic_di->cur_pos; + uint64_t sample = _snapshot->get_sample(cur_pos) & logic_di->logic_mask; + if (logic_di->edge_index == -1) { + std::vector pos_vector; + cur_pos++; + for (int j =0 ; j < logic_di->dec_num_channels; j++) { + int index = logic_di->dec_channelmap[j]; + if (index != -1 && (logic_di->logic_mask & (1 << index))) { + bool last_sample = (sample & (1 << index)) ? 1 : 0; + pos_vector.push_back(cur_pos); + _snapshot->get_nxt_edge(pos_vector.back(), last_sample, decode_end, 1, index); + } + } + cur_pos = *std::min_element(pos_vector.begin(), pos_vector.end()); + } else { + bool last_sample = (sample & (1 << logic_di->edge_index)) ? 1 : 0; + do { + cur_pos++; + if (!_snapshot->get_nxt_edge(cur_pos, last_sample, decode_end, 1, logic_di->edge_index)) + break; + sample = _snapshot->get_sample(cur_pos) & logic_di->logic_mask; + last_sample = (sample & (1 << logic_di->edge_index)) ? 1 : 0; + } while(sample != logic_di->exp_logic); + } + + i = cur_pos; + if (i >= decode_end) + i = decode_end; + chunk_type = 0; + } else { + i += chunk_sample_count; + chunk_type = 1; + } + { lock_guard lock(_output_mutex); - _samples_decoded = chunk_end - decode_start + 1; + _samples_decoded = i - decode_start + 1; } if ((i - last_cnt) > notify_cnt) { last_cnt = i; new_decode_data(); } - } _options_changed = false; decode_done(); diff --git a/DSView/pv/data/decoderstack.h b/DSView/pv/data/decoderstack.h index 40be16db..143ad01d 100644 --- a/DSView/pv/data/decoderstack.h +++ b/DSView/pv/data/decoderstack.h @@ -20,8 +20,7 @@ #ifndef DSVIEW_PV_DATA_DECODERSTACK_H #define DSVIEW_PV_DATA_DECODERSTACK_H - -#include "signaldata.h" +#include #include @@ -32,14 +31,9 @@ #include #include -#include -#include - -struct srd_decoder; -struct srd_decoder_annotation_row; -struct srd_channel; -struct srd_proto_data; -struct srd_session; +#include <../data/decode/row.h> +#include <../data/decode/rowdata.h> +#include <../data/signaldata.h> namespace DecoderStackTest { class TwoDecoderStack; diff --git a/DSView/pv/data/logicsnapshot.cpp b/DSView/pv/data/logicsnapshot.cpp index df77821f..edea2467 100644 --- a/DSView/pv/data/logicsnapshot.cpp +++ b/DSView/pv/data/logicsnapshot.cpp @@ -23,6 +23,8 @@ #include +#include + #include #include #include @@ -208,25 +210,25 @@ void LogicSnapshot::get_subsampled_edges( uint64_t start, uint64_t end, float min_length, int sig_index) { - uint64_t index = start; - bool last_sample; + if (!edges.empty()) + edges.clear(); - assert(end <= get_sample_count()); + if (_sample_count == 0) + return; + + assert(end < _sample_count); assert(start <= end); assert(min_length > 0); assert(sig_index >= 0); assert(sig_index < 64); - if (_data.size() == 0) - return; - boost::lock_guard lock(_mutex); - + uint64_t index = start; + bool last_sample; const uint64_t block_length = (uint64_t)max(min_length, 1.0f); const uint64_t sig_mask = 1ULL << sig_index; - if (!edges.empty()) - edges.clear(); + // Store the initial state last_sample = (get_sample(start) & sig_mask) != 0; edges.push_back(pair(index++, last_sample)); diff --git a/DSView/pv/data/snapshot.cpp b/DSView/pv/data/snapshot.cpp index e5e9e741..c68d03ae 100644 --- a/DSView/pv/data/snapshot.cpp +++ b/DSView/pv/data/snapshot.cpp @@ -23,6 +23,8 @@ #include "snapshot.h" +#include + #include #include #include diff --git a/DSView/pv/dock/dsotriggerdock.cpp b/DSView/pv/dock/dsotriggerdock.cpp index f825695d..a6d99456 100644 --- a/DSView/pv/dock/dsotriggerdock.cpp +++ b/DSView/pv/dock/dsotriggerdock.cpp @@ -155,10 +155,10 @@ DsoTriggerDock::~DsoTriggerDock() void DsoTriggerDock::paintEvent(QPaintEvent *) { - QStyleOption opt; - opt.init(this); - QPainter p(this); - style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); +// QStyleOption opt; +// opt.init(this); +// QPainter p(this); +// style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); } void DsoTriggerDock::pos_changed(int pos) diff --git a/DSView/pv/dock/measuredock.cpp b/DSView/pv/dock/measuredock.cpp index c49f0743..67a7e2fe 100644 --- a/DSView/pv/dock/measuredock.cpp +++ b/DSView/pv/dock/measuredock.cpp @@ -147,10 +147,10 @@ MeasureDock::~MeasureDock() void MeasureDock::paintEvent(QPaintEvent *) { - QStyleOption opt; - opt.init(this); - QPainter p(this); - style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); +// QStyleOption opt; +// opt.init(this); +// QPainter p(this); +// style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); } void MeasureDock::cursor_update() diff --git a/DSView/pv/dock/searchdock.cpp b/DSView/pv/dock/searchdock.cpp index 17fe110c..90b1bbab 100644 --- a/DSView/pv/dock/searchdock.cpp +++ b/DSView/pv/dock/searchdock.cpp @@ -102,10 +102,10 @@ SearchDock::~SearchDock() void SearchDock::paintEvent(QPaintEvent *) { - QStyleOption opt; - opt.init(this); - QPainter p(this); - style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); +// QStyleOption opt; +// opt.init(this); +// QPainter p(this); +// style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); } void SearchDock::on_previous() diff --git a/DSView/pv/dock/triggerdock.cpp b/DSView/pv/dock/triggerdock.cpp index 6dc4ca6d..a16eb34e 100644 --- a/DSView/pv/dock/triggerdock.cpp +++ b/DSView/pv/dock/triggerdock.cpp @@ -271,10 +271,10 @@ TriggerDock::~TriggerDock() void TriggerDock::paintEvent(QPaintEvent *) { - QStyleOption opt; - opt.init(this); - QPainter p(this); - style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); +// QStyleOption opt; +// opt.init(this); +// QPainter p(this); +// style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); } void TriggerDock::simple_trigger() diff --git a/DSView/pv/mainwindow.cpp b/DSView/pv/mainwindow.cpp index 57ca57f2..42e81399 100644 --- a/DSView/pv/mainwindow.cpp +++ b/DSView/pv/mainwindow.cpp @@ -112,7 +112,7 @@ void MainWindow::setup_ui() { setObjectName(QString::fromUtf8("MainWindow")); setMinimumHeight(680); - setMinimumWidth(500); + setMinimumWidth(800); resize(1024, 768); // Set the window icon diff --git a/DSView/pv/view/decodetrace.cpp b/DSView/pv/view/decodetrace.cpp index b47de76c..e16c0f8b 100644 --- a/DSView/pv/view/decodetrace.cpp +++ b/DSView/pv/view/decodetrace.cpp @@ -197,6 +197,41 @@ void DecodeTrace::paint_back(QPainter &p, int left, int right) p.drawPolygon(start_points, countof(start_points)); p.drawPolygon(end_points, countof(end_points)); + // --draw headings + const int row_height = _view->get_signalHeight(); + for (size_t i = 0; i < _cur_row_headings.size(); i++) + { + const int y = i * row_height + get_y() - _totalHeight * 0.5; + + p.setPen(QPen(Qt::NoPen)); + p.setBrush(QApplication::palette().brush(QPalette::WindowText)); + + const QRect r(left + ArrowSize * 2, y, + right - left, row_height / 2); + const QString h(_cur_row_headings[i]); + const int f = Qt::AlignLeft | Qt::AlignVCenter | + Qt::TextDontClip; + const QPointF points[] = { + QPointF(left, r.center().y() - ArrowSize), + QPointF(left + ArrowSize, r.center().y()), + QPointF(left, r.center().y() + ArrowSize) + }; + p.drawPolygon(points, countof(points)); + + // Draw the outline + QFont font=p.font(); + font.setPointSize(DefaultFontSize); + p.setFont(font); +// p.setPen(QApplication::palette().color(QPalette::Base)); +// for (int dx = -1; dx <= 1; dx++) +// for (int dy = -1; dy <= 1; dy++) +// if (dx != 0 && dy != 0) +// p.drawText(r.translated(dx, dy), f, h); + + // Draw the text + p.setPen(DARK_FORE); + p.drawText(r, f, h); + } } void DecodeTrace::paint_mid(QPainter &p, int left, int right) @@ -300,45 +335,45 @@ void DecodeTrace::paint_fore(QPainter &p, int left, int right) (void)right; - const int row_height = _view->get_signalHeight(); +// const int row_height = _view->get_signalHeight(); - for (size_t i = 0; i < _cur_row_headings.size(); i++) - { - const int y = (i + 0.5) * row_height + get_y() - _totalHeight * 0.5; +// for (size_t i = 0; i < _cur_row_headings.size(); i++) +// { +// const int y = (i + 0.5) * row_height + get_y() - _totalHeight * 0.5; - p.setPen(QPen(Qt::NoPen)); - p.setBrush(QApplication::palette().brush(QPalette::WindowText)); +// p.setPen(QPen(Qt::NoPen)); +// p.setBrush(QApplication::palette().brush(QPalette::WindowText)); - if (i != 0) - { - const QPointF points[] = { - QPointF(left, y - ArrowSize), - QPointF(left + ArrowSize, y), - QPointF(left, y + ArrowSize) - }; - p.drawPolygon(points, countof(points)); - } +// if (i != 0) +// { +// const QPointF points[] = { +// QPointF(left, y - ArrowSize), +// QPointF(left + ArrowSize, y), +// QPointF(left, y + ArrowSize) +// }; +// p.drawPolygon(points, countof(points)); +// } - const QRect r(left + ArrowSize * 2, y - row_height / 2, - right - left, row_height); - const QString h(_cur_row_headings[i]); - const int f = Qt::AlignLeft | Qt::AlignBottom | - Qt::TextDontClip; +// const QRect r(left + ArrowSize * 2, y - row_height / 2, +// right - left, row_height); +// const QString h(_cur_row_headings[i]); +// const int f = Qt::AlignLeft | Qt::AlignBottom | +// Qt::TextDontClip; - // Draw the outline - QFont font=p.font(); - font.setPointSize(DefaultFontSize); - p.setFont(font); - p.setPen(QApplication::palette().color(QPalette::Base)); - for (int dx = -1; dx <= 1; dx++) - for (int dy = -1; dy <= 1; dy++) - if (dx != 0 && dy != 0) - p.drawText(r.translated(dx, dy), f, h); +// // Draw the outline +// QFont font=p.font(); +// font.setPointSize(DefaultFontSize); +// p.setFont(font); +//// p.setPen(QApplication::palette().color(QPalette::Base)); +//// for (int dx = -1; dx <= 1; dx++) +//// for (int dy = -1; dy <= 1; dy++) +//// if (dx != 0 && dy != 0) +//// p.drawText(r.translated(dx, dy), f, h); - // Draw the text - p.setPen(QApplication::palette().color(QPalette::WindowText)); - p.drawText(r, f, h); - } +// // Draw the text +// p.setPen(DARK_FORE); +// p.drawText(r, f, h); +// } } bool DecodeTrace::create_popup() @@ -506,7 +541,7 @@ void DecodeTrace::draw_nodetail(QPainter &p, size_t base_colour) const { const QRectF nodetail_rect(left, y - h/2 + 0.5, right - left, h); - QString info = tr("Zoom in For Detial"); + QString info = tr("Zoom in For Detials"); int info_left = nodetail_rect.center().x() - p.boundingRect(QRectF(), 0, info).width(); int info_right = nodetail_rect.center().x() + p.boundingRect(QRectF(), 0, info).width(); int height = p.boundingRect(QRectF(), 0, info).height(); diff --git a/DSView/pv/view/header.cpp b/DSView/pv/view/header.cpp index a490805b..2eb1d5fb 100644 --- a/DSView/pv/view/header.cpp +++ b/DSView/pv/view/header.cpp @@ -119,7 +119,7 @@ void Header::paintEvent(QPaintEvent*) //painter.setRenderHint(QPainter::Antialiasing); style()->drawPrimitive(QStyle::PE_Widget, &o, &painter, this); - painter.begin(this); + //painter.begin(this); const int w = width(); const vector< boost::shared_ptr > traces( diff --git a/DSView/pv/view/logicsignal.cpp b/DSView/pv/view/logicsignal.cpp index fb911fd7..09a43232 100644 --- a/DSView/pv/view/logicsignal.cpp +++ b/DSView/pv/view/logicsignal.cpp @@ -23,6 +23,8 @@ #include +#include + #include #include "logicsignal.h" diff --git a/DSView/pv/view/ruler.cpp b/DSView/pv/view/ruler.cpp index 171d99de..209a75a1 100644 --- a/DSView/pv/view/ruler.cpp +++ b/DSView/pv/view/ruler.cpp @@ -182,7 +182,7 @@ void Ruler::paintEvent(QPaintEvent*) QPainter p(this); style()->drawPrimitive(QStyle::PE_Widget, &o, &p, this); - p.begin(this); + //p.begin(this); //QPainter p(this); //p.setRenderHint(QPainter::Antialiasing); diff --git a/DSView/pv/view/viewport.cpp b/DSView/pv/view/viewport.cpp index 7d5c87f7..9197f0ce 100644 --- a/DSView/pv/view/viewport.cpp +++ b/DSView/pv/view/viewport.cpp @@ -128,7 +128,7 @@ void Viewport::paintEvent(QPaintEvent *event) QPainter p(this); style()->drawPrimitive(QStyle::PE_Widget, &o, &p, this); - p.begin(this); + //p.begin(this); const vector< boost::shared_ptr > traces(_view.get_traces(_type)); BOOST_FOREACH(const boost::shared_ptr t, traces) {