Initial rendering of traces
authorJoel Holdsworth <joel@airwebreathe.org.uk>
Mon, 11 Jun 2012 21:17:34 +0000 (22:17 +0100)
committerJoel Holdsworth <joel@airwebreathe.org.uk>
Mon, 3 Sep 2012 12:59:04 +0000 (13:59 +0100)
logicdata.cpp
logicdata.h
logicdatasnapshot.cpp
logicdatasnapshot.h
logicsignal.cpp
logicsignal.h
signal.cpp
signal.h
signaldata.cpp
signaldata.h

index 8fe32ed92fe6c01d701c50efce7020d0b380771e..1c6aa59e1d5fc463912ca4d4311ec7adc9a4cfcb 100644 (file)
@@ -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<LogicDataSnapshot> >& LogicData::get_snapshots()
+{
+       return _snapshots;
+}
index f835db5ca9f8f9786b93491b11731090fb256dde..9c7e4b9782d3cd3d7092a84426304d858f8a9b38 100644 (file)
@@ -20,6 +20,9 @@
 
 #include "signaldata.h"
 
+#include <boost/shared_ptr.hpp>
+#include <queue>
+
 extern "C" {
 #include <libsigrok/libsigrok.h>
 }
@@ -36,6 +39,11 @@ public:
        void push_snapshot(
                boost::shared_ptr<LogicDataSnapshot> &snapshot);
 
+       std::queue< boost::shared_ptr<LogicDataSnapshot> >&
+               get_snapshots();
+
 private:
        const int _num_probes;
+       std::queue< boost::shared_ptr<LogicDataSnapshot> >
+               _snapshots;
 };
index 755c81dfb793dfed36a0d14ce13fc20b211dec85..032d9c81e464f2dd3311fd31a076a83073aa34a1 100644 (file)
@@ -22,7 +22,7 @@
 
 #include <assert.h>
 
-#include <QDebug>
+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<EdgePair> &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<int64_t, bool>(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<int64_t, bool>(
+                               final_index, final_sample));
+
+                       // Continue to sampling
+                       i = final_index;
+                       last_sample = final_sample;
+               }
+       }
+
+       // Add the final state
+       edges.push_back(pair<int64_t, bool>(end - 1,
+               get_sample(end - 1) & sig_mask));
+}
index f321f6cf6e031904e185c5be4b9f89630d41484b..e6fee52bea70f88aad01ee18c8522636930c4bc7 100644 (file)
 
 #include "datasnapshot.h"
 
+#include <utility>
+#include <vector>
+
 class LogicDataSnapshot : public DataSnapshot
 {
+public:
+       typedef std::pair<int64_t, bool> 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<EdgePair> &edges,
+               int64_t start, int64_t end,
+               int64_t quantization_length, int sig_index);
 };
index 8f984ea7ab4616c5d054cbedd01f09a5e88dfe76..1587bddd473002d4264d47abafd118d5c3c0cfd2 100644 (file)
 #include <GL/gl.h>
 #include <GL/glext.h>
 
+#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<SignalData> data,
+LogicSignal::LogicSignal(QString name, shared_ptr<LogicData> 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<SignalData> data,
 void LogicSignal::paint(QGLWidget &widget, const QRect &rect,
        uint64_t scale, int64_t offset)
 {
-       GLuint vbo_id;
+       Point2F *vertex;
+
+       vector< pair<int64_t, bool> > edges;
+
+       assert(_data);
+
+       const queue< shared_ptr<LogicDataSnapshot> > &snapshots =
+               _data->get_snapshots();
+       if(snapshots.empty())
+               return;
+
+       const shared_ptr<LogicDataSnapshot> &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<LogicDataSnapshot::EdgePair>::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<LogicDataSnapshot::EdgePair>::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);
 }
index 28c8247a90c7cb3d43ed358e4c388c2f43116ab2..324d072cc92e2bc90f274fe434e82616d4fa1b07 100644 (file)
@@ -26,8 +26,15 @@ class LogicData;
 
 class LogicSignal : public Signal
 {
+private:
+       struct Point2F
+       {
+               GLfloat x, y;
+       };
+
 public:
-       LogicSignal(QString name, boost::shared_ptr<SignalData> data,
+       LogicSignal(QString name,
+               boost::shared_ptr<LogicData> 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<LogicData> _data;
 };
index 476a5a256c179c1eb4e55528f186940d637aa0e0..d35be6bfed5dfecae1382525f2885732ec9ff206 100644 (file)
@@ -22,9 +22,8 @@
 
 #include <memory.h>
 
-Signal::Signal(QString name, boost::shared_ptr<SignalData> data) :
-       _name(name),
-       _data(data)
+Signal::Signal(QString name) :
+       _name(name)
 {
 }
 
index 2cec1299e0cce040cf78d90a0441933c4512e9ce..d55f6dbed429d4624a6bc22a011d43bed4c808f3 100644 (file)
--- a/signal.h
+++ b/signal.h
@@ -31,7 +31,7 @@ class SignalData;
 class Signal
 {
 protected:
-       Signal(QString name, boost::shared_ptr<SignalData> data);
+       Signal(QString name);
 
 public:
        QString get_name() const;
@@ -49,5 +49,4 @@ public:
 
 protected:
        QString _name;
-       boost::shared_ptr<SignalData> _data;
 };
index 8588e5daa308388eab4f3cc71ba942d6d8adaed0..fbc10133fc9ee5c88228086e3700a2a1e0d4daf6 100644 (file)
 
 #include "signaldata.h"
 
+using namespace std;
+
 SignalData::SignalData(uint64_t samplerate) :
-       _samplerate(samplerate)
+       _samplerate(samplerate),
+       _start_time(0)
 {
 }
index 74d1facd3bc944c24368282ccdf7aec6628ca47d..18c9b3d5767b6c4f4ecc303449602f6730e2cba1 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
  */
 
-#include <boost/shared_ptr.hpp>
-#include <queue>
 #include <stdint.h>
 
-class DataSnapshot;
-
 class SignalData
 {
 public:
@@ -31,6 +27,5 @@ public:
 
 protected:
        const uint64_t _samplerate;
-
-       std::queue< boost::shared_ptr<DataSnapshot> > _snapshots;
+       const int64_t _start_time;
 };