From: Joel Holdsworth Date: Mon, 11 Jun 2012 21:17:34 +0000 (+0100) Subject: Initial rendering of traces X-Git-Tag: pulseview-0.1.0~343 X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=2858b391af20bd46c9a7da17195ec8d58bcd12c3;p=pulseview.git Initial rendering of traces --- diff --git a/logicdata.cpp b/logicdata.cpp index 8fe32ed9..1c6aa59e 100644 --- a/logicdata.cpp +++ b/logicdata.cpp @@ -22,6 +22,7 @@ #include "logicdatasnapshot.h" using namespace boost; +using namespace std; LogicData::LogicData(const sr_datafeed_meta_logic &meta) : SignalData(meta.samplerate), @@ -39,3 +40,8 @@ void LogicData::push_snapshot( { _snapshots.push(snapshot); } + +queue< shared_ptr >& LogicData::get_snapshots() +{ + return _snapshots; +} diff --git a/logicdata.h b/logicdata.h index f835db5c..9c7e4b97 100644 --- a/logicdata.h +++ b/logicdata.h @@ -20,6 +20,9 @@ #include "signaldata.h" +#include +#include + extern "C" { #include } @@ -36,6 +39,11 @@ public: void push_snapshot( boost::shared_ptr &snapshot); + std::queue< boost::shared_ptr >& + get_snapshots(); + private: const int _num_probes; + std::queue< boost::shared_ptr > + _snapshots; }; diff --git a/logicdatasnapshot.cpp b/logicdatasnapshot.cpp index 755c81df..032d9c81 100644 --- a/logicdatasnapshot.cpp +++ b/logicdatasnapshot.cpp @@ -22,7 +22,7 @@ #include -#include +using namespace std; LogicDataSnapshot::LogicDataSnapshot( const sr_datafeed_logic &logic) : @@ -36,8 +36,59 @@ void LogicDataSnapshot::append_payload( { assert(_unit_size == logic.unitsize); - qDebug() << "SR_DF_LOGIC (length =" << logic.length - << ", unitsize = " << logic.unitsize << ")"; - append_data(logic.data, logic.length); } + +uint64_t LogicDataSnapshot::get_sample(uint64_t index) const +{ + assert(_data); + assert(index >= 0 && index < _data_length); + + return *(uint64_t*)((uint8_t*)_data + index * _unit_size); +} + +void LogicDataSnapshot::get_subsampled_edges( + std::vector &edges, + int64_t start, int64_t end, + int64_t quantization_length, int sig_index) +{ + assert(start >= 0); + assert(end < get_sample_count()); + assert(start <= end); + assert(quantization_length > 0); + assert(sig_index >= 0); + assert(sig_index < SR_MAX_NUM_PROBES); + + const uint64_t sig_mask = 1 << sig_index; + + // Add the initial state + bool last_sample = get_sample(start) & sig_mask; + edges.push_back(pair(start, last_sample)); + + for(int64_t i = start + 1; i < end - 1; i++) + { + const bool sample = get_sample(i) & sig_mask; + + // Check if we hit an edge + if(sample != last_sample) + { + // Take the last sample of the quanization block + const int64_t final_index = + min((i - (i % quantization_length) + + quantization_length - 1), end); + + // Store the final state + const bool final_sample = get_sample(final_index) & sig_mask; + edges.push_back(pair( + final_index, final_sample)); + + // Continue to sampling + i = final_index; + last_sample = final_sample; + } + } + + // Add the final state + edges.push_back(pair(end - 1, + get_sample(end - 1) & sig_mask)); +} diff --git a/logicdatasnapshot.h b/logicdatasnapshot.h index f321f6cf..e6fee52b 100644 --- a/logicdatasnapshot.h +++ b/logicdatasnapshot.h @@ -20,10 +20,32 @@ #include "datasnapshot.h" +#include +#include + class LogicDataSnapshot : public DataSnapshot { +public: + typedef std::pair EdgePair; + public: LogicDataSnapshot(const sr_datafeed_logic &logic); void append_payload(const sr_datafeed_logic &logic); + + uint64_t get_sample(uint64_t index) const; + + /** + * Parses a logic data snapshot to generate a list of transitions + * in a time interval to a given level of detail. + * @param[out] edges The vector to place the edges into. + * @param[in] start The start sample index. + * @param[in] end The end sample index. + * @param[in] quantization_length The minimum period of time that + * can be resolved at this level of detail. + * @param[in] sig_index The index of the signal. + **/ + void get_subsampled_edges(std::vector &edges, + int64_t start, int64_t end, + int64_t quantization_length, int sig_index); }; diff --git a/logicsignal.cpp b/logicsignal.cpp index 8f984ea7..1587bddd 100644 --- a/logicsignal.cpp +++ b/logicsignal.cpp @@ -22,16 +22,17 @@ #include #include +#include "logicdata.h" +#include "logicdatasnapshot.h" #include "logicsignal.h" -struct LogicVertex -{ - GLfloat x, y; -}; +using namespace boost; +using namespace std; -LogicSignal::LogicSignal(QString name, boost::shared_ptr data, +LogicSignal::LogicSignal(QString name, shared_ptr data, int probe_index) : - Signal(name, data), + Signal(name), + _data(data), _probe_index(probe_index) { assert(_probe_index >= 0); @@ -40,28 +41,93 @@ LogicSignal::LogicSignal(QString name, boost::shared_ptr data, void LogicSignal::paint(QGLWidget &widget, const QRect &rect, uint64_t scale, int64_t offset) { - GLuint vbo_id; + Point2F *vertex; + + vector< pair > edges; + + assert(_data); + + const queue< shared_ptr > &snapshots = + _data->get_snapshots(); + if(snapshots.empty()) + return; + + const shared_ptr &snapshot = snapshots.front(); + + const int64_t start = 0; + const int64_t end = 8000; + const int64_t quantization_length = 4; + + snapshot->get_subsampled_edges(edges, start, end, + quantization_length, _probe_index); + + // Paint the edges + const unsigned int edge_point_count = (edges.size() - 2) * 2; + Point2F *const edge_points = new Point2F[edge_point_count]; + vertex = edge_points; + + for(vector::const_iterator i = edges.begin() + 1; + i != edges.end() - 1; i++) + { + const int x = edge.first / quantization_length + + rect.left(); + + vertex->x = x, vertex->y = 10 + rect.top() - 1; + vertex++; + vertex->x = x, vertex->y = 40 + rect.top(); + vertex++; + } glColor3f(0,0,1); - LogicVertex vetices[3]; - vetices[0].x = rect.left(); - vetices[0].y = rect.top(); - vetices[1].x = rect.right(); - vetices[1].y = rect.bottom(); - vetices[2].x = rect.right(); - vetices[2].y = rect.top(); + paint_lines(edge_points, edge_point_count); + delete[] edge_points; + + // Paint the caps + const unsigned int cap_point_count = (edges.size() - 1) * 2; + Point2F *const cap_points = new Point2F[cap_point_count]; + vertex = cap_points; + + for(vector::const_iterator i = edges.begin(); + i != (edges.end() - 1); i++) + { + const int y = ((*i).second ? 10 : 40) + rect.top(); + + vertex->x = (*i).first / quantization_length + + rect.left() - 1; + vertex->y = y; + vertex++; + + vertex->x = (*(i+1)).first / quantization_length + + rect.left(); + vertex->y = y; + vertex++; + } + + glColor3f(0,0,1); + paint_lines(cap_points, cap_point_count); + delete[] cap_points; +} + +void LogicSignal::paint_lines(Point2F *points, int count) +{ + GLuint vbo_id; + + assert(points); glGenBuffers(1, &vbo_id); glBindBuffer(GL_ARRAY_BUFFER, vbo_id); - glBufferData(GL_ARRAY_BUFFER, sizeof(vetices), NULL, GL_STATIC_DRAW); - glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vetices), vetices); + const unsigned int vbo_length = count * sizeof(Point2F); + glBufferData(GL_ARRAY_BUFFER, vbo_length, NULL, GL_STATIC_DRAW); + glBufferSubData(GL_ARRAY_BUFFER, 0, vbo_length, points); glBindBuffer(GL_ARRAY_BUFFER, vbo_id); - glVertexPointer(2, GL_FLOAT, sizeof(LogicVertex), 0); + glVertexPointer(2, GL_FLOAT, sizeof(Point2F), 0); glEnableClientState(GL_VERTEX_ARRAY); - glDrawArrays(GL_LINE_STRIP, 0, 2); + glDrawArrays(GL_LINES, 0, count); glDisableClientState(GL_VERTEX_ARRAY); + + glDeleteBuffers(1, &vbo_id); } diff --git a/logicsignal.h b/logicsignal.h index 28c8247a..324d072c 100644 --- a/logicsignal.h +++ b/logicsignal.h @@ -26,8 +26,15 @@ class LogicData; class LogicSignal : public Signal { +private: + struct Point2F + { + GLfloat x, y; + }; + public: - LogicSignal(QString name, boost::shared_ptr data, + LogicSignal(QString name, + boost::shared_ptr data, int probe_index); /** @@ -41,6 +48,10 @@ public: void paint(QGLWidget &widget, const QRect &rect, uint64_t scale, int64_t offset); +private: + static void paint_lines(Point2F *points, int count); + private: int _probe_index; + boost::shared_ptr _data; }; diff --git a/signal.cpp b/signal.cpp index 476a5a25..d35be6bf 100644 --- a/signal.cpp +++ b/signal.cpp @@ -22,9 +22,8 @@ #include -Signal::Signal(QString name, boost::shared_ptr data) : - _name(name), - _data(data) +Signal::Signal(QString name) : + _name(name) { } diff --git a/signal.h b/signal.h index 2cec1299..d55f6dbe 100644 --- a/signal.h +++ b/signal.h @@ -31,7 +31,7 @@ class SignalData; class Signal { protected: - Signal(QString name, boost::shared_ptr data); + Signal(QString name); public: QString get_name() const; @@ -49,5 +49,4 @@ public: protected: QString _name; - boost::shared_ptr _data; }; diff --git a/signaldata.cpp b/signaldata.cpp index 8588e5da..fbc10133 100644 --- a/signaldata.cpp +++ b/signaldata.cpp @@ -20,7 +20,10 @@ #include "signaldata.h" +using namespace std; + SignalData::SignalData(uint64_t samplerate) : - _samplerate(samplerate) + _samplerate(samplerate), + _start_time(0) { } diff --git a/signaldata.h b/signaldata.h index 74d1facd..18c9b3d5 100644 --- a/signaldata.h +++ b/signaldata.h @@ -18,12 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include #include -class DataSnapshot; - class SignalData { public: @@ -31,6 +27,5 @@ public: protected: const uint64_t _samplerate; - - std::queue< boost::shared_ptr > _snapshots; + const int64_t _start_time; };