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().
const double DecodeSignal::DecodeMargin = 1.0;
const double DecodeSignal::DecodeThreshold = 0.2;
const int64_t DecodeSignal::DecodeChunkLength = 10 * 1024 * 1024;
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_;
mutex DecodeSignal::global_srd_mutex_;
logic_mux_data_invalid_(false),
start_time_(0),
samplerate_(0),
logic_mux_data_invalid_(false),
start_time_(0),
samplerate_(0),
samples_decoded_(0),
frame_complete_(false)
{
samples_decoded_(0),
frame_complete_(false)
{
frame_complete_ = false;
samples_decoded_ = 0;
error_message_ = QString();
frame_complete_ = false;
samples_decoded_ = 0;
error_message_ = QString();
// TODO Restore decoder stack, channel mapping and decoder options
}
// TODO Restore decoder stack, channel mapping and decoder options
}
-uint64_t DecodeSignal::inc_annotation_count()
-{
- return (annotation_count_++);
-}
-
void DecodeSignal::update_channel_list()
{
vector<data::DecodeChannel> prev_channels = channels_;
void DecodeSignal::update_channel_list()
{
vector<data::DecodeChannel> prev_channels = channels_;
+ // Notify the frontend that we processed some data and
+ // possibly have new annotations as well
+ new_annotations();
+
{
lock_guard<mutex> lock(output_mutex_);
samples_decoded_ = chunk_end;
{
lock_guard<mutex> lock(output_mutex_);
samples_decoded_ = chunk_end;
} while (error_message_.isEmpty() && (sample_count > 0));
if (error_message_.isEmpty()) {
} 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<mutex> input_wait_lock(input_mutex_);
decode_input_cond_.wait(input_wait_lock);
// Wait for new input data or an interrupt was requested
unique_lock<mutex> input_wait_lock(input_mutex_);
decode_input_cond_.wait(input_wait_lock);
// Add the annotation
(*row_iter).second.push_annotation(a);
// 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)
}
void DecodeSignal::on_capture_state_changed(int state)
static const double DecodeMargin;
static const double DecodeThreshold;
static const int64_t DecodeChunkLength;
static const double DecodeMargin;
static const double DecodeThreshold;
static const int64_t DecodeChunkLength;
- static const unsigned int DecodeNotifyPeriod;
public:
DecodeSignal(pv::Session &session);
public:
DecodeSignal(pv::Session &session);
virtual void restore_settings(QSettings &settings);
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();
private:
void update_channel_list();
pv::util::Timestamp start_time_;
double samplerate_;
pv::util::Timestamp start_time_;
double samplerate_;
- int64_t annotation_count_, samples_decoded_;
+ int64_t samples_decoded_;
vector< shared_ptr<decode::Decoder> > stack_;
map<const decode::Row, decode::RowData> rows_;
vector< shared_ptr<decode::Decoder> > stack_;
map<const decode::Row, decode::RowData> rows_;
const int DecodeTrace::RowTitleMargin = 10;
const int DecodeTrace::DrawPadding = 100;
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),
const QColor DecodeTrace::Colours[16] = {
QColor(0xEF, 0x29, 0x29),
QColor(0xF6, 0x6A, 0x32),
this, SLOT(on_delete_decoder(int)));
connect(&show_hide_mapper_, SIGNAL(mapped(int)),
this, SLOT(on_show_hide_decoder(int)));
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
}
bool DecodeTrace::enabled() const
}
void DecodeTrace::on_new_annotations()
}
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);
{
if (owner_)
owner_->row_item_appearance_changed(false, true);
#include <QComboBox>
#include <QSignalMapper>
#include <QComboBox>
#include <QSignalMapper>
#include <pv/binding/decoder.hpp>
#include <pv/data/decode/row.hpp>
#include <pv/binding/decoder.hpp>
#include <pv/data/decode/row.hpp>
static const int RowTitleMargin;
static const int DrawPadding;
static const int RowTitleMargin;
static const int DrawPadding;
+ static const int MaxTraceUpdateRate;
+
static const QColor Colours[16];
static const QColor OutlineColours[16];
static const QColor Colours[16];
static const QColor OutlineColours[16];
private Q_SLOTS:
void on_new_annotations();
private Q_SLOTS:
void on_new_annotations();
+ void on_delayed_trace_update();
int min_useful_label_width_;
QSignalMapper delete_mapper_, show_hide_mapper_;
int min_useful_label_width_;
QSignalMapper delete_mapper_, show_hide_mapper_;
+
+ QTimer delayed_trace_updater_;