ViewPort: Make ViewItemPaintParams mutable
[pulseview.git] / pv / view / analogsignal.cpp
index af979c0c2d8a6500358538138e2e89cc9adeccf6..b9d73126527a3f0a1820d8ce60a94e228a42fd14 100644 (file)
@@ -40,9 +40,9 @@
 #include "pv/data/logic.hpp"
 #include "pv/data/logicsegment.hpp"
 #include "pv/data/signalbase.hpp"
-#include "pv/view/view.hpp"
-#include "pv/view/logicsignal.hpp"
 #include "pv/globalsettings.hpp"
+#include "pv/view/logicsignal.hpp"
+#include "pv/view/view.hpp"
 
 #include <libsigrokcxx/libsigrokcxx.hpp>
 
@@ -73,7 +73,8 @@ const QColor AnalogSignal::GridMinorColor = QColor(0, 0, 0, 20 * 256 / 100);
 
 const QColor AnalogSignal::SamplingPointColour(0x77, 0x77, 0x77);
 
-const float AnalogSignal::EnvelopeThreshold = 256.0f;
+const int64_t AnalogSignal::TracePaintBlockSize = 1024 * 1024;  // 4 MiB (due to float)
+const float AnalogSignal::EnvelopeThreshold = 64.0f;
 
 const int AnalogSignal::MaximumVDivs = 10;
 const int AnalogSignal::MinScaleIndex = -6;
@@ -175,7 +176,7 @@ void AnalogSignal::scale_handle_drag_release()
        update_scale();
 }
 
-void AnalogSignal::paint_back(QPainter &p, const ViewItemPaintParams &pp)
+void AnalogSignal::paint_back(QPainter &p, ViewItemPaintParams &pp)
 {
        if (base_->enabled()) {
                Trace::paint_back(p, pp);
@@ -183,7 +184,7 @@ void AnalogSignal::paint_back(QPainter &p, const ViewItemPaintParams &pp)
        }
 }
 
-void AnalogSignal::paint_mid(QPainter &p, const ViewItemPaintParams &pp)
+void AnalogSignal::paint_mid(QPainter &p, ViewItemPaintParams &pp)
 {
        assert(base_->analog_data());
        assert(owner_);
@@ -236,7 +237,7 @@ void AnalogSignal::paint_mid(QPainter &p, const ViewItemPaintParams &pp)
        }
 }
 
-void AnalogSignal::paint_fore(QPainter &p, const ViewItemPaintParams &pp)
+void AnalogSignal::paint_fore(QPainter &p, ViewItemPaintParams &pp)
 {
        if (!enabled())
                return;
@@ -263,13 +264,19 @@ void AnalogSignal::paint_grid(QPainter &p, int y, int left, int right)
 {
        p.setRenderHint(QPainter::Antialiasing, false);
 
+       GlobalSettings settings;
+       const bool show_analog_minor_grid =
+               settings.value(GlobalSettings::Key_View_ShowAnalogMinorGrid).toBool();
+
        if (pos_vdivs_ > 0) {
                p.setPen(QPen(GridMajorColor, 1, Qt::DashLine));
                for (int i = 1; i <= pos_vdivs_; i++) {
                        const float dy = i * div_height_;
                        p.drawLine(QLineF(left, y - dy, right, y - dy));
                }
+       }
 
+       if ((pos_vdivs_ > 0) && show_analog_minor_grid) {
                p.setPen(QPen(GridMinorColor, 1, Qt::DashLine));
                for (int i = 0; i < pos_vdivs_; i++) {
                        const float dy = i * div_height_;
@@ -288,7 +295,9 @@ void AnalogSignal::paint_grid(QPainter &p, int y, int left, int right)
                        const float dy = i * div_height_;
                        p.drawLine(QLineF(left, y + dy, right, y + dy));
                }
+       }
 
+       if ((pos_vdivs_ > 0) && show_analog_minor_grid) {
                p.setPen(QPen(GridMinorColor, 1, Qt::DashLine));
                for (int i = 0; i < neg_vdivs_; i++) {
                        const float dy = i * div_height_;
@@ -309,6 +318,15 @@ void AnalogSignal::paint_trace(QPainter &p,
        int y, int left, const int64_t start, const int64_t end,
        const double pixels_offset, const double samples_per_pixel)
 {
+       if (end <= start)
+               return;
+
+       // Calculate and paint the sampling points if enabled and useful
+       GlobalSettings settings;
+       const bool show_sampling_points =
+               settings.value(GlobalSettings::Key_View_ShowSamplingPoints).toBool() &&
+               (samples_per_pixel < 0.25);
+
        p.setPen(base_->colour());
 
        const int64_t points_count = end - start;
@@ -316,38 +334,45 @@ void AnalogSignal::paint_trace(QPainter &p,
        QPointF *points = new QPointF[points_count];
        QPointF *point = points;
 
-       QRectF *const sampling_points = new QRectF[points_count];
+       QRectF *sampling_points = nullptr;
+       if (show_sampling_points)
+                sampling_points = new QRectF[points_count];
        QRectF *sampling_point = sampling_points;
 
-       pv::data::SegmentAnalogDataIterator* it =
-               segment->begin_sample_iteration(start);
+       int64_t sample_count = min(points_count, TracePaintBlockSize);
+       int64_t block_sample = 0;
+       const float *sample_block = segment->get_samples(start, start + sample_count);
 
        const int w = 2;
-       for (int64_t sample = start; sample != end; sample++) {
+       for (int64_t sample = start; sample != end; sample++, block_sample++) {
+
+               if (block_sample == TracePaintBlockSize) {
+                       block_sample = 0;
+                       delete[] sample_block;
+                       sample_count = min(points_count - sample, TracePaintBlockSize);
+                       sample_block = segment->get_samples(sample, sample + sample_count);
+               }
+
                const float x = (sample / samples_per_pixel -
                        pixels_offset) + left;
 
-               *point++ = QPointF(x, y - *((float*)it->value) * scale_);
-               *sampling_point++ = QRectF(x - (w / 2), y - *((float*)it->value) * scale_ - (w / 2), w, w);
+               *point++ = QPointF(x, y - sample_block[block_sample] * scale_);
 
-               segment->continue_sample_iteration(it, 1);
+               if (show_sampling_points)
+                       *sampling_point++ =
+                               QRectF(x - (w / 2), y - sample_block[block_sample] * scale_ - (w / 2), w, w);
        }
-       segment->end_sample_iteration(it);
+       delete[] sample_block;
 
        p.drawPolyline(points, points_count);
 
-       // Paint the sampling points if enabled
-       GlobalSettings settings;
-       const bool show_sampling_points =
-               settings.value(GlobalSettings::Key_View_ShowSamplingPoints).toBool();
-
-       if (show_sampling_points && (samples_per_pixel < 0.25)) {
+       if (show_sampling_points) {
                p.setPen(SamplingPointColour);
                p.drawRects(sampling_points, points_count);
+               delete[] sampling_points;
        }
 
        delete[] points;
-       delete[] sampling_points;
 }
 
 void AnalogSignal::paint_envelope(QPainter &p,
@@ -395,7 +420,7 @@ void AnalogSignal::paint_envelope(QPainter &p,
        delete[] e.samples;
 }
 
-void AnalogSignal::paint_logic_mid(QPainter &p, const ViewItemPaintParams &pp)
+void AnalogSignal::paint_logic_mid(QPainter &p, ViewItemPaintParams &pp)
 {
        QLineF *line;