From: Soeren Apel Date: Tue, 4 Jul 2017 19:23:30 +0000 (+0200) Subject: DecodeTrace/DecodeSignal: Rework trace drawing interval X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=5b6ae10391736ab2f81de851686dee15bbcbf9f9;p=pulseview.git DecodeTrace/DecodeSignal: Rework trace drawing interval Before, we'd redraw the decode trace every n annotations that came in. However, that causes a lot of unnecessary redraws when we're zoomed out relatively far and makes the UI less responsive in return. Instead, use a one-shot timer with a fixed delay to redraw the trace after data has been processed. This way, there is an upper bound to how often we redraw the trace while at the same time providing a fixed interval at which we update, regardless of how many annotations came in, making the trace fill up continuously. With that in place, we can also remove annotation_count_ and inc_annotation_count(). --- diff --git a/pv/data/decodesignal.cpp b/pv/data/decodesignal.cpp index 37956889..a2fe8f63 100644 --- a/pv/data/decodesignal.cpp +++ b/pv/data/decodesignal.cpp @@ -47,7 +47,6 @@ namespace data { const double DecodeSignal::DecodeMargin = 1.0; const double DecodeSignal::DecodeThreshold = 0.2; const int64_t DecodeSignal::DecodeChunkLength = 10 * 1024 * 1024; -const unsigned int DecodeSignal::DecodeNotifyPeriod = 1024; mutex DecodeSignal::global_srd_mutex_; @@ -59,7 +58,6 @@ DecodeSignal::DecodeSignal(pv::Session &session) : logic_mux_data_invalid_(false), start_time_(0), samplerate_(0), - annotation_count_(0), samples_decoded_(0), frame_complete_(false) { @@ -148,7 +146,6 @@ void DecodeSignal::reset_decode() { stop_srd_session(); - annotation_count_ = 0; frame_complete_ = false; samples_decoded_ = 0; error_message_ = QString(); @@ -415,11 +412,6 @@ void DecodeSignal::restore_settings(QSettings &settings) // TODO Restore decoder stack, channel mapping and decoder options } -uint64_t DecodeSignal::inc_annotation_count() -{ - return (annotation_count_++); -} - void DecodeSignal::update_channel_list() { vector prev_channels = channels_; @@ -675,6 +667,10 @@ void DecodeSignal::decode_data( delete[] chunk; + // Notify the frontend that we processed some data and + // possibly have new annotations as well + new_annotations(); + { lock_guard lock(output_mutex_); samples_decoded_ = chunk_end; @@ -711,9 +707,6 @@ void DecodeSignal::decode_proc() } while (error_message_.isEmpty() && (sample_count > 0)); if (error_message_.isEmpty()) { - // Make sure all annotations are known to the frontend - new_annotations(); - // Wait for new input data or an interrupt was requested unique_lock input_wait_lock(input_mutex_); decode_input_cond_.wait(input_wait_lock); @@ -821,10 +814,6 @@ void DecodeSignal::annotation_callback(srd_proto_data *pdata, void *decode_signa // Add the annotation (*row_iter).second.push_annotation(a); - - // Notify the frontend every DecodeNotifyPeriod annotations - if (ds->inc_annotation_count() % DecodeNotifyPeriod == 0) - ds->new_annotations(); } void DecodeSignal::on_capture_state_changed(int state) diff --git a/pv/data/decodesignal.hpp b/pv/data/decodesignal.hpp index 57887f1e..1d6c1ab4 100644 --- a/pv/data/decodesignal.hpp +++ b/pv/data/decodesignal.hpp @@ -79,7 +79,6 @@ private: static const double DecodeMargin; static const double DecodeThreshold; static const int64_t DecodeChunkLength; - static const unsigned int DecodeNotifyPeriod; public: DecodeSignal(pv::Session &session); @@ -129,13 +128,6 @@ public: virtual void restore_settings(QSettings &settings); - /** - * Helper function for static annotation_callback(), - * must be public so the function can access it. - * Don't use from outside this class. - */ - uint64_t inc_annotation_count(); - private: void update_channel_list(); @@ -180,7 +172,7 @@ private: pv::util::Timestamp start_time_; double samplerate_; - int64_t annotation_count_, samples_decoded_; + int64_t samples_decoded_; vector< shared_ptr > stack_; map rows_; diff --git a/pv/views/trace/decodetrace.cpp b/pv/views/trace/decodetrace.cpp index d8f04c58..f4ab55ff 100644 --- a/pv/views/trace/decodetrace.cpp +++ b/pv/views/trace/decodetrace.cpp @@ -90,6 +90,8 @@ const double DecodeTrace::EndCapWidth = 5; const int DecodeTrace::RowTitleMargin = 10; const int DecodeTrace::DrawPadding = 100; +const int DecodeTrace::MaxTraceUpdateRate = 1; // No more than 1 Hz + const QColor DecodeTrace::Colours[16] = { QColor(0xEF, 0x29, 0x29), QColor(0xF6, 0x6A, 0x32), @@ -154,6 +156,11 @@ DecodeTrace::DecodeTrace(pv::Session &session, this, SLOT(on_delete_decoder(int))); connect(&show_hide_mapper_, SIGNAL(mapped(int)), this, SLOT(on_show_hide_decoder(int))); + + connect(&delayed_trace_updater_, SIGNAL(timeout()), + this, SLOT(on_delayed_trace_update())); + delayed_trace_updater_.setSingleShot(true); + delayed_trace_updater_.setInterval(1000 / MaxTraceUpdateRate); } bool DecodeTrace::enabled() const @@ -865,6 +872,12 @@ QComboBox* DecodeTrace::create_channel_selector_init_state(QWidget *parent, } void DecodeTrace::on_new_annotations() +{ + if (!delayed_trace_updater_.isActive()) + delayed_trace_updater_.start(); +} + +void DecodeTrace::on_delayed_trace_update() { if (owner_) owner_->row_item_appearance_changed(false, true); diff --git a/pv/views/trace/decodetrace.hpp b/pv/views/trace/decodetrace.hpp index 7edb30bd..6ba48455 100644 --- a/pv/views/trace/decodetrace.hpp +++ b/pv/views/trace/decodetrace.hpp @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -82,6 +83,8 @@ private: static const int RowTitleMargin; static const int DrawPadding; + static const int MaxTraceUpdateRate; + static const QColor Colours[16]; static const QColor OutlineColours[16]; @@ -180,6 +183,7 @@ public: private Q_SLOTS: void on_new_annotations(); + void on_delayed_trace_update(); void on_delete(); @@ -214,6 +218,8 @@ private: int min_useful_label_width_; QSignalMapper delete_mapper_, show_hide_mapper_; + + QTimer delayed_trace_updater_; }; } // namespace trace