From: Soeren Apel Date: Tue, 27 Jun 2017 16:32:30 +0000 (+0200) Subject: Decode: Improve signaling X-Git-Url: https://sigrok.org/gitweb/?p=pulseview.git;a=commitdiff_plain;h=1b56c646e7dd253775b4d6cfceaf327fd8ffd297 Decode: Improve signaling Three issues that were fixed by this: 1) The SignalBase did notify PDs when its conversion changed and new sample data was generated but this was dismissed as the samples_cleared() signal was never fired nor used by the PD stack. 2) The decode_finished() signal was added so that the decode trace can immediately paint the trace once the PD is done. Before, a repaint was only triggered when annotations came in, resulting in a noticeable "unresolved period" visible if the last stretch of signal didn't contain any annotations as the trace wasn't repainted quickly enough. 3) The decode trace indirectly looks at the signal's samples_decoded_ member when drawing the "unresolved period" bar. Hence we should update this member before triggering the repaint via new_annotations(). --- diff --git a/pv/data/decodesignal.cpp b/pv/data/decodesignal.cpp index e8206a08..be2ed161 100644 --- a/pv/data/decodesignal.cpp +++ b/pv/data/decodesignal.cpp @@ -69,19 +69,7 @@ DecodeSignal::DecodeSignal(pv::Session &session) : DecodeSignal::~DecodeSignal() { - if (decode_thread_.joinable()) { - decode_interrupt_ = true; - decode_input_cond_.notify_one(); - decode_thread_.join(); - } - - if (logic_mux_thread_.joinable()) { - logic_mux_interrupt_ = true; - logic_mux_cond_.notify_one(); - logic_mux_thread_.join(); - } - - stop_srd_session(); + reset_decode(); } const vector< shared_ptr >& DecodeSignal::decoder_stack() const @@ -144,13 +132,29 @@ bool DecodeSignal::toggle_decoder_visibility(int index) void DecodeSignal::reset_decode() { + if (decode_thread_.joinable()) { + decode_interrupt_ = true; + decode_input_cond_.notify_one(); + decode_thread_.join(); + } + + if (logic_mux_thread_.joinable()) { + logic_mux_interrupt_ = true; + logic_mux_cond_.notify_one(); + logic_mux_thread_.join(); + } + stop_srd_session(); frame_complete_ = false; samples_decoded_ = 0; error_message_ = QString(); + rows_.clear(); class_rows_.clear(); + + logic_mux_data_.reset(); + logic_mux_data_invalid_ = true; } void DecodeSignal::begin_decode() @@ -674,14 +678,14 @@ 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; } + + // Notify the frontend that we processed some data and + // possibly have new annotations as well + new_annotations(); } } @@ -711,9 +715,12 @@ void DecodeSignal::decode_proc() decode_data(abs_start_samplenum, sample_count); abs_start_samplenum += sample_count; } - } while (error_message_.isEmpty() && (sample_count > 0)); + } while (error_message_.isEmpty() && (sample_count > 0) && !decode_interrupt_); + + if (error_message_.isEmpty() && !decode_interrupt_) { + if (sample_count == 0) + decode_finished(); - if (error_message_.isEmpty()) { // Wait for new input data or an interrupt was requested unique_lock input_wait_lock(input_mutex_); decode_input_cond_.wait(input_wait_lock); @@ -769,6 +776,7 @@ void DecodeSignal::stop_srd_session() void DecodeSignal::connect_input_notifiers() { // Disconnect the notification slot from the previous set of signals + disconnect(this, SLOT(on_data_cleared())); disconnect(this, SLOT(on_data_received())); // Connect the currently used signals to our slot @@ -776,8 +784,10 @@ void DecodeSignal::connect_input_notifiers() if (!ch.assigned_signal) continue; - shared_ptr logic_data = ch.assigned_signal->logic_data(); - connect(logic_data.get(), SIGNAL(samples_added(QObject*, uint64_t, uint64_t)), + const data::SignalBase *signal = ch.assigned_signal; + connect(signal, SIGNAL(samples_cleared()), + this, SLOT(on_data_cleared())); + connect(signal, SIGNAL(samples_added(QObject*, uint64_t, uint64_t)), this, SLOT(on_data_received())); } } @@ -830,9 +840,17 @@ void DecodeSignal::on_capture_state_changed(int state) begin_decode(); } +void DecodeSignal::on_data_cleared() +{ + reset_decode(); +} + void DecodeSignal::on_data_received() { - logic_mux_cond_.notify_one(); + if (!logic_mux_thread_.joinable()) + begin_decode(); + else + logic_mux_cond_.notify_one(); } } // namespace data diff --git a/pv/data/decodesignal.hpp b/pv/data/decodesignal.hpp index 1d6c1ab4..86b19318 100644 --- a/pv/data/decodesignal.hpp +++ b/pv/data/decodesignal.hpp @@ -152,10 +152,12 @@ private: Q_SIGNALS: void new_annotations(); + void decode_finished(); void channels_updated(); private Q_SLOTS: void on_capture_state_changed(int state); + void on_data_cleared(); void on_data_received(); private: diff --git a/pv/data/signalbase.cpp b/pv/data/signalbase.cpp index 173610d9..3c0305a5 100644 --- a/pv/data/signalbase.cpp +++ b/pv/data/signalbase.cpp @@ -181,6 +181,7 @@ void SignalBase::set_conversion_type(ConversionType t) // Discard converted data converted_data_.reset(); + samples_cleared(); } conversion_type_ = t; diff --git a/pv/views/trace/decodetrace.cpp b/pv/views/trace/decodetrace.cpp index f4ab55ff..21d88923 100644 --- a/pv/views/trace/decodetrace.cpp +++ b/pv/views/trace/decodetrace.cpp @@ -149,6 +149,8 @@ DecodeTrace::DecodeTrace(pv::Session &session, connect(decode_signal_.get(), SIGNAL(new_annotations()), this, SLOT(on_new_annotations())); + connect(decode_signal_.get(), SIGNAL(decode_finished()), + this, SLOT(on_decode_finished())); connect(decode_signal_.get(), SIGNAL(channels_updated()), this, SLOT(on_channels_updated())); @@ -883,6 +885,12 @@ void DecodeTrace::on_delayed_trace_update() owner_->row_item_appearance_changed(false, true); } +void DecodeTrace::on_decode_finished() +{ + if (owner_) + owner_->row_item_appearance_changed(false, true); +} + void DecodeTrace::delete_pressed() { on_delete(); diff --git a/pv/views/trace/decodetrace.hpp b/pv/views/trace/decodetrace.hpp index 6ba48455..26da3ace 100644 --- a/pv/views/trace/decodetrace.hpp +++ b/pv/views/trace/decodetrace.hpp @@ -184,6 +184,7 @@ public: private Q_SLOTS: void on_new_annotations(); void on_delayed_trace_update(); + void on_decode_finished(); void on_delete();