Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: ngscopeclient/scopehal-apps
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 1bea07858458
Choose a base ref
...
head repository: ngscopeclient/scopehal-apps
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 6fcae18b2221
Choose a head ref
  • 3 commits
  • 7 files changed
  • 1 contributor

Commits on Sep 5, 2020

  1. Copy the full SHA
    10b0e80 View commit details
  2. Copy the full SHA
    b11ddcb View commit details
  3. Copy the full SHA
    6fcae18 View commit details
79 changes: 57 additions & 22 deletions src/glscopeclient/OscilloscopeWindow.cpp
Original file line number Diff line number Diff line change
@@ -1843,9 +1843,11 @@ void OscilloscopeWindow::OnZoomOutHorizontal(WaveformGroup* group, int64_t targe
ClearPersistence(group);
}

void OscilloscopeWindow::ClearPersistence(WaveformGroup* group, bool dirty)
void OscilloscopeWindow::ClearPersistence(WaveformGroup* group, bool geometry_dirty, bool position_dirty)
{
//Make the list of stuff being updated
auto children = group->m_vbox.get_children();
vector<WaveformArea*> areas;
for(auto w : children)
{
//Redraw all views in the waveform box
@@ -1858,17 +1860,47 @@ void OscilloscopeWindow::ClearPersistence(WaveformGroup* group, bool dirty)
//Clear persistence on waveform areas
auto area = dynamic_cast<WaveformArea*>(a);
if(area != NULL)
{
if(dirty)
area->SetGeometryDirty();
area->ClearPersistence();
}
areas.push_back(area);
}
}
}

//Redraw everything (timeline included)
w->queue_draw();
//Mark each area as dirty and map the buffers needed for update
for(auto w : areas)
{
w->ClearPersistence(false);

if(geometry_dirty)
w->MapAllBuffers(true);
else if(position_dirty)
w->MapAllBuffers(false);
}

//Do the actual updates
float alpha = GetTraceAlpha();
if(geometry_dirty || position_dirty)
{
//Make the list of data to update
vector<WaveformRenderData*> data;
for(auto w : areas)
w->GetAllRenderData(data);

//Do the updates in parallel
#pragma omp parallel for
for(size_t i=0; i<data.size(); i++)
WaveformArea::PrepareGeometry(data[i], geometry_dirty, alpha);

//Clean up
for(auto w : areas)
{
w->SetNotDirty();
w->UnmapAllBuffers(geometry_dirty);
}
}

//Submit update requests for each area (and the timeline)
for(auto w : children)
w->queue_draw();
}

void OscilloscopeWindow::ClearAllPersistence()
@@ -2073,29 +2105,32 @@ void OscilloscopeWindow::OnAllWaveformsUpdated()
for(auto a : m_analyzers)
a->OnWaveformDataReady();

//Make a vector of our waveform areas so we can parallelize PrepareAllGeometry() calls
//(OpenMP can't iterate over a set)
vector<WaveformArea*> areas;
//Map all of the buffers we need to update in each area
for(auto w : m_waveformAreas)
areas.push_back(w);
w->MapAllBuffers(true);

//Map all GL buffers for every waveform area (has to be done in main thread)
float alpha = GetTraceAlpha();

//Make the list of data to update (waveforms plus overlays)
vector<WaveformRenderData*> data;
for(auto w : m_waveformAreas)
w->MapAllBuffers();
w->GetAllRenderData(data);

//Do geometry conversion in as many threads as we can
double start = GetTime();
//Do the updates in parallel
#pragma omp parallel for
for(size_t i=0; i<areas.size(); i++)
areas[i]->PrepareAllGeometry();
for(size_t i=0; i<data.size(); i++)
WaveformArea::PrepareGeometry(data[i], true, alpha);

//Unmap the buffers (has to be done in main thread) and tell them to update
//Clean up
for(auto w : m_waveformAreas)
{
w->UnmapAllBuffers();
w->OnWaveformDataReady();
w->SetNotDirty();
w->UnmapAllBuffers(true);
}
m_tView += GetTime() - start;

//Submit update requests for each area
for(auto w : m_waveformAreas)
w->queue_draw();

//Update the trigger sync wizard, if it's active
if(m_scopeSyncWizard && m_scopeSyncWizard->is_visible())
2 changes: 1 addition & 1 deletion src/glscopeclient/OscilloscopeWindow.h
Original file line number Diff line number Diff line change
@@ -56,7 +56,7 @@ class OscilloscopeWindow : public Gtk::Window
void OnAutofitHorizontal();
void OnZoomInHorizontal(WaveformGroup* group, int64_t target);
void OnZoomOutHorizontal(WaveformGroup* group, int64_t target);
void ClearPersistence(WaveformGroup* group, bool dirty = true);
void ClearPersistence(WaveformGroup* group, bool geometry_dirty = true, bool position_dirty = false);
void ClearAllPersistence();

void OnRemoveChannel(WaveformArea* w);
2 changes: 1 addition & 1 deletion src/glscopeclient/Timeline.cpp
Original file line number Diff line number Diff line change
@@ -114,7 +114,7 @@ bool Timeline::on_motion_notify_event(GdkEventMotion* event)
m_group->m_xAxisOffset = m_originalTimeOffset - ps;

//Clear persistence and redraw the group (fixes #46)
m_group->GetParent()->ClearPersistence(m_group, false);
m_group->GetParent()->ClearPersistence(m_group, false, true);
}
break;

3 changes: 2 additions & 1 deletion src/glscopeclient/WaveformArea.cpp
Original file line number Diff line number Diff line change
@@ -95,6 +95,7 @@ void WaveformArea::SharedCtorInit()
m_waveformRenderData = NULL;
m_dragOverlayPosition = 0;
m_geometryDirty = false;
m_positionDirty = false;
m_mouseElementPosition = LOC_PLOT;

m_decodeDialog = NULL;
@@ -591,7 +592,7 @@ void WaveformArea::on_realize()
m_firstFrame = true;

//Create waveform render data for our main trace
m_waveformRenderData = new WaveformRenderData(m_channel);
m_waveformRenderData = new WaveformRenderData(m_channel, this);

//Set stuff up for each rendering pass
InitializeWaveformPass();
42 changes: 29 additions & 13 deletions src/glscopeclient/WaveformArea.h
Original file line number Diff line number Diff line change
@@ -78,21 +78,26 @@ class Rect : public Gdk::Rectangle
}
};

class WaveformArea;

/**
@rbief GL buffers etc needed to render a single waveform
@brief GL buffers etc needed to render a single waveform
*/
class WaveformRenderData
{
public:
WaveformRenderData(StreamDescriptor channel)
: m_channel(channel)
WaveformRenderData(StreamDescriptor channel, WaveformArea* area)
: m_area(area)
, m_channel(channel)
, m_geometryOK(false)
, m_count(0)
{}

bool IsDigital()
{ return m_channel.m_channel->GetType() == OscilloscopeChannel::CHANNEL_TYPE_DIGITAL; }

WaveformArea* m_area;

//The channel of interest
StreamDescriptor m_channel;

@@ -121,8 +126,8 @@ class WaveformRenderData
float* m_mappedFloatConfigBuffer;

//Map all buffers for download
void MapBuffers(size_t width);
void UnmapBuffers();
void MapBuffers(size_t width, bool update_waveform = true);
void UnmapBuffers(bool update_waveform = true);
};

float sinc(float x, float width);
@@ -142,15 +147,25 @@ class WaveformArea : public Gtk::GLArea
StreamDescriptor GetChannel()
{ return m_channel; }

void ClearPersistence()
void ClearPersistence(bool geometry_dirty = true)
{
m_persistenceClear = true;
SetGeometryDirty();
if(geometry_dirty)
SetGeometryDirty();
}

void SetGeometryDirty()
{ m_geometryDirty = true; }

void SetPositionDirty()
{ m_positionDirty = true; }

void SetNotDirty()
{
m_positionDirty = false;
m_geometryDirty = false;
}

WaveformGroup* m_group;

//Helpers for figuring out what kind of signal our primary trace is
@@ -179,10 +194,11 @@ class WaveformArea : public Gtk::GLArea
m_overlays.push_back(stream);
}

//Calls PrepareGeometry() for all waveforms
void PrepareAllGeometry();
void MapAllBuffers();
void UnmapAllBuffers();
//Helper to get all geometry that needs to be updated
void GetAllRenderData(std::vector<WaveformRenderData*>& data);
static void PrepareGeometry(WaveformRenderData* wdata, bool update_waveform, float alpha);
void MapAllBuffers(bool update_y);
void UnmapAllBuffers(bool update_y);

void CenterTimestamp(int64_t time);

@@ -317,7 +333,6 @@ class WaveformArea : public Gtk::GLArea
//Trace rendering
void RenderTrace(WaveformRenderData* wdata);
void InitializeWaveformPass();
void PrepareGeometry(WaveformRenderData* wdata);
Program m_analogWaveformComputeProgram;
Program m_digitalWaveformComputeProgram;
WaveformRenderData* m_waveformRenderData;
@@ -407,7 +422,7 @@ class WaveformArea : public Gtk::GLArea
float XAxisUnitsToPixels(int64_t t);
float XAxisUnitsToXPosition(int64_t t);
float PickStepSize(float volts_per_half_span, int min_steps = 2, int max_steps = 5);
template<class T> size_t BinarySearchForGequal(T* buf, size_t len, T value);
template<class T> static size_t BinarySearchForGequal(T* buf, size_t len, T value);
float GetValueAtTime(int64_t time_ps);

void OnRemoveOverlay(StreamDescriptor filter);
@@ -486,6 +501,7 @@ class WaveformArea : public Gtk::GLArea

bool m_firstFrame;
bool m_geometryDirty;
bool m_positionDirty;
};

#endif
2 changes: 1 addition & 1 deletion src/glscopeclient/WaveformArea_events.cpp
Original file line number Diff line number Diff line change
@@ -1329,5 +1329,5 @@ void WaveformArea::CenterTimestamp(int64_t time)
//Figure out how wide our view is, then offset the point by half that
int64_t width = PixelsToXAxisUnits(m_width);
m_group->m_xAxisOffset = time - width/2;
m_parent->ClearPersistence(m_group);
m_parent->ClearPersistence(m_group, false, true);
}
Loading