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: 376f37b6a758
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: d6a4a2f677c0
Choose a head ref
  • 1 commit
  • 8 files changed
  • 1 contributor

Commits on Feb 14, 2020

  1. PrepareGeometry() now keeps track of dirty flag and only re-tesselate…

    …s if new waveform data is ready or LOD has changed. Fixed unnecessary re-renders of unchanged scenery. Fixes #46.
    azonenberg committed Feb 14, 2020
    Copy the full SHA
    d6a4a2f View commit details
47 changes: 31 additions & 16 deletions glscopeclient/OscilloscopeWindow.cpp
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
* *
* ANTIKERNEL v0.1 *
* *
* Copyright (c) 2012-2019 Andrew D. Zonenberg *
* Copyright (c) 2012-2020 Andrew D. Zonenberg *
* All rights reserved. *
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the *
@@ -528,24 +528,39 @@ void OscilloscopeWindow::OnAutofitHorizontal()
void OscilloscopeWindow::OnZoomInHorizontal(WaveformGroup* group)
{
group->m_pixelsPerPicosecond *= 1.5;
LogDebug("zoom in\n");
ClearPersistence(group);
}

void OscilloscopeWindow::OnZoomOutHorizontal(WaveformGroup* group)
{
group->m_pixelsPerPicosecond /= 1.5;
LogDebug("zoom out\n");
ClearPersistence(group);
}

void OscilloscopeWindow::ClearPersistence(WaveformGroup* group)
void OscilloscopeWindow::ClearPersistence(WaveformGroup* group, bool dirty)
{
auto children = group->m_vbox.get_children();
for(auto w : children)
{
//Clear persistence on waveform areas
auto area = dynamic_cast<WaveformArea*>(w);
if(area != NULL)
area->ClearPersistence();
//Redraw all views in the waveform box
auto box = dynamic_cast<Gtk::Box*>(w);
if(box)
{
auto bchildren = box->get_children();
for(auto a : bchildren)
{
//Clear persistence on waveform areas
auto area = dynamic_cast<WaveformArea*>(a);
if(area != NULL)
{
if(dirty)
area->SetGeometryDirty();
area->ClearPersistence();
}
}
}

//Redraw everything (timeline included)
w->queue_draw();
@@ -648,19 +663,19 @@ void OscilloscopeWindow::PollScopes()
m_tPoll += GetTime() - start;

//If triggered, grab the data
if(status == Oscilloscope::TRIGGER_MODE_TRIGGERED)
if(status != Oscilloscope::TRIGGER_MODE_TRIGGERED)
continue;

//If we have a LOT of waveforms ready, don't waste time rendering all of them.
//Grab a big pile and only render the last.
//TODO: batch render with persistence?
if(scope->GetPendingWaveformCount() > 30)
{
//If we have a LOT of waveforms ready, don't waste time rendering all of them.
//Grab a big pile and only render the last.
//TODO: batch render with persistence?
if(scope->GetPendingWaveformCount() > 30)
{
for(size_t i=0; i<25; i++)
OnWaveformDataReady(scope);
}
else
for(size_t i=0; i<25; i++)
OnWaveformDataReady(scope);
}
else
OnWaveformDataReady(scope);

//Update the views
start = GetTime();
2 changes: 1 addition & 1 deletion glscopeclient/OscilloscopeWindow.h
Original file line number Diff line number Diff line change
@@ -54,7 +54,7 @@ class OscilloscopeWindow : public Gtk::Window
void OnAutofitHorizontal();
void OnZoomInHorizontal(WaveformGroup* group);
void OnZoomOutHorizontal(WaveformGroup* group);
void ClearPersistence(WaveformGroup* group);
void ClearPersistence(WaveformGroup* group, bool dirty = true);
void ClearAllPersistence();

void OnRemoveChannel(WaveformArea* w);
7 changes: 5 additions & 2 deletions glscopeclient/Timeline.cpp
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
* *
* ANTIKERNEL v0.1 *
* *
* Copyright (c) 2012-2019 Andrew D. Zonenberg *
* Copyright (c) 2012-2020 Andrew D. Zonenberg *
* All rights reserved. *
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the *
@@ -26,10 +26,12 @@
* POSSIBILITY OF SUCH DAMAGE. *
* *
***********************************************************************************************************************/

#include "glscopeclient.h"
#include "WaveformGroup.h"
#include "Timeline.h"
#include "WaveformArea.h"
#include "OscilloscopeWindow.h"

using namespace std;

@@ -94,7 +96,8 @@ bool Timeline::on_motion_notify_event(GdkEventMotion* event)
if(m_group->m_timeOffset < 0)
m_group->m_timeOffset = 0;

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

2 changes: 2 additions & 0 deletions glscopeclient/WaveformArea.cpp
Original file line number Diff line number Diff line change
@@ -68,6 +68,7 @@ WaveformArea::WaveformArea(const WaveformArea* clone)
, m_channel(clone->m_channel)
, m_parent(clone->m_parent)
, m_pixelsPerVolt(clone->m_pixelsPerVolt)
, m_msaaEnabled(clone->m_msaaEnabled)
{
SharedCtorInit();
}
@@ -87,6 +88,7 @@ void WaveformArea::SharedCtorInit()
m_padding = 2;
m_lastFrameStart = -1;
m_persistenceClear = true;
m_geometryDirty = true;

set_has_alpha();

4 changes: 4 additions & 0 deletions glscopeclient/WaveformArea.h
Original file line number Diff line number Diff line change
@@ -57,6 +57,9 @@ class WaveformArea : public Gtk::GLArea
void ClearPersistence()
{ m_persistenceClear = true; }

void SetGeometryDirty()
{ m_geometryDirty = true; }

WaveformGroup* m_group;

//Helpers for figuring out what kind of signal our primary trace is
@@ -291,6 +294,7 @@ class WaveformArea : public Gtk::GLArea
} m_dragState;

bool m_msaaEnabled;
bool m_geometryDirty;
};

#endif
11 changes: 5 additions & 6 deletions glscopeclient/WaveformArea_events.cpp
Original file line number Diff line number Diff line change
@@ -121,6 +121,8 @@ void WaveformArea::on_resize(int width, int height)
if(!m_waveformFramebufferResolved.IsComplete())
LogError("FBO is incomplete: %x\n", glCheckFramebufferStatus(GL_FRAMEBUFFER));

SetGeometryDirty();

err = glGetError();
if(err != 0)
LogNotice("resize 4, err = %x\n", err);
@@ -156,17 +158,11 @@ bool WaveformArea::on_scroll_event (GdkEventScroll* ev)
{
case GDK_SCROLL_UP:
if(!IsEye())
{
m_parent->OnZoomInHorizontal(m_group);
ClearPersistence();
}
break;
case GDK_SCROLL_DOWN:
if(!IsEye())
{
m_parent->OnZoomOutHorizontal(m_group);
ClearPersistence();
}
break;
case GDK_SCROLL_LEFT:
LogDebug("scroll left\n");
@@ -188,10 +184,12 @@ bool WaveformArea::on_scroll_event (GdkEventScroll* ev)
{
case GDK_SCROLL_UP:
m_channel->SetVoltageRange(vrange * 0.9);
SetGeometryDirty();
queue_draw();
break;
case GDK_SCROLL_DOWN:
m_channel->SetVoltageRange(vrange / 0.9);
SetGeometryDirty();
queue_draw();
break;

@@ -570,6 +568,7 @@ void WaveformArea::OnWaveformDataReady()
}

//Update our measurements and redraw the waveform
SetGeometryDirty();
queue_draw();
m_group->m_timeline.queue_draw();
}
20 changes: 13 additions & 7 deletions glscopeclient/WaveformArea_rendering.cpp
Original file line number Diff line number Diff line change
@@ -50,26 +50,31 @@ using namespace glm;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Rendering

//TODO: only do this if the waveform is dirty!
//TODO: Tesselate in a shader, rather than on the CPU!
bool WaveformArea::PrepareGeometry()
{
double start = GetTime();

//LogDebug("Processing capture\n");
//LogIndenter li;

//Look up some configuration and update the X axis offset
auto pdat = dynamic_cast<AnalogCapture*>(m_channel->GetData());
if(!pdat)
return false;
AnalogCapture& data = *pdat;
m_xoff = (pdat->m_triggerPhase - m_group->m_timeOffset) * m_group->m_pixelsPerPicosecond;
size_t count = data.size();
if(count == 0)
return false;

//Early out if nothing has changed.
//glBufferData() and tesselation are expensive, only do them if changing LOD or new waveform data
if(!m_geometryDirty)
return true;

double start = GetTime();

//LogDebug("Processing capture\n");
//LogIndenter li;

//Create the geometry
double offset = m_channel->GetOffset();
m_xoff = (pdat->m_triggerPhase - m_group->m_timeOffset) * m_group->m_pixelsPerPicosecond;
double xscale = pdat->m_timescale * m_group->m_pixelsPerPicosecond;
bool fft = IsFFT();

@@ -176,6 +181,7 @@ bool WaveformArea::PrepareGeometry()
dt = GetTime() - start;
m_downloadTime += dt;

m_geometryDirty = false;
return true;
}

5 changes: 4 additions & 1 deletion glscopeclient/WaveformGroup.h
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
* *
* ANTIKERNEL v0.1 *
* *
* Copyright (c) 2012-2019 Andrew D. Zonenberg *
* Copyright (c) 2012-2020 Andrew D. Zonenberg *
* All rights reserved. *
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the *
@@ -90,6 +90,9 @@ class WaveformGroup
int64_t m_xCursorPos[2];
double m_yCursorPos[2];

OscilloscopeWindow* GetParent()
{ return m_parent; }

protected:
MeasurementColumn* m_selectedColumn;
bool OnMeasurementContextMenu(GdkEventButton* event, MeasurementColumn* col);