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: eb239067ff7b
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: f1d95f5afbe2
Choose a head ref
  • 1 commit
  • 10 files changed
  • 1 contributor

Commits on Dec 19, 2020

  1. Copy the full SHA
    f1d95f5 View commit details
2 changes: 1 addition & 1 deletion lib
16 changes: 14 additions & 2 deletions src/glscopeclient/OscilloscopeWindow.cpp
Original file line number Diff line number Diff line change
@@ -2259,13 +2259,19 @@ void OscilloscopeWindow::ClearPersistence(WaveformGroup* group, bool geometry_di
{
//Make the list of data to update
vector<WaveformRenderData*> data;
float coeff = -1;
for(auto w : areas)
{
if(coeff < 0)
coeff = w->GetPersistenceDecayCoefficient();

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);
WaveformArea::PrepareGeometry(data[i], geometry_dirty, alpha, coeff);

//Clean up
for(auto w : areas)
@@ -2533,13 +2539,19 @@ void OscilloscopeWindow::OnAllWaveformsUpdated()

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

if(coeff < 0)
coeff = w->GetPersistenceDecayCoefficient();
}

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

//Clean up
for(auto w : m_waveformAreas)
5 changes: 5 additions & 0 deletions src/glscopeclient/PreferenceSchema.cpp
Original file line number Diff line number Diff line change
@@ -233,6 +233,11 @@ void PreferenceManager::InitializeDefaults()
Preference::Font("y_axis_font", "monospace normal 10")
.Label("Y axis font")
.Description("Font used for text on the vertical axis of waveforms"));
waveforms.AddPreference(
Preference::Real("persist_decay_rate", 0.9)
.Label("Persistence decay rate (0 = none, 1 = infinite)")
.Description("Decay rate for persistence waveforms. ")
.Unit(Unit::UNIT_COUNTS));

auto& windows = appearance.AddCategory("Windows");
windows.AddPreference(
33 changes: 0 additions & 33 deletions src/glscopeclient/WaveformArea.cpp
Original file line number Diff line number Diff line change
@@ -563,7 +563,6 @@ void WaveformArea::on_realize()
//Set stuff up for each rendering pass
InitializeWaveformPass();
InitializeColormapPass();
InitializePersistencePass();
InitializeCairoPass();
InitializeEyePass();
}
@@ -584,19 +583,16 @@ void WaveformArea::CleanupGLHandles()
m_digitalWaveformComputeProgram.Destroy();
m_analogWaveformComputeProgram.Destroy();
m_colormapProgram.Destroy();
m_persistProgram.Destroy();
m_eyeProgram.Destroy();
m_cairoProgram.Destroy();

//Clean up old VAOs
m_colormapVAO.Destroy();
m_persistVAO.Destroy();
m_cairoVAO.Destroy();
m_eyeVAO.Destroy();

//Clean up old VBOs
m_colormapVBO.Destroy();
m_persistVBO.Destroy();
m_cairoVBO.Destroy();
m_eyeVBO.Destroy();

@@ -736,35 +732,6 @@ void WaveformArea::InitializeEyePass()
}
}

void WaveformArea::InitializePersistencePass()
{
//Set up shaders
VertexShader cvs;
FragmentShader cfs;
if(!cvs.Load("shaders/persist-vertex.glsl") || !cfs.Load("shaders/persist-fragment.glsl"))
LogFatal("failed to load persist shaders, aborting\n");

m_persistProgram.Add(cvs);
m_persistProgram.Add(cfs);
if(!m_persistProgram.Link())
LogFatal("failed to link shader program, aborting\n");

//Create the VAO/VBO for a fullscreen polygon
float verts[8] =
{
-1, -1,
1, -1,
1, 1,
-1, 1
};
m_persistVBO.Bind();
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);

m_persistVAO.Bind();
m_persistProgram.EnableVertexArray("vert");
m_persistProgram.SetVertexAttribPointer("vert", 2, 0);
}

void WaveformArea::InitializeCairoPass()
{
//Set up shaders
15 changes: 7 additions & 8 deletions src/glscopeclient/WaveformArea.h
Original file line number Diff line number Diff line change
@@ -62,6 +62,7 @@ class WaveformRenderData
, m_mappedConfigBuffer(NULL)
, m_mappedConfigBuffer64(NULL)
, m_mappedFloatConfigBuffer(NULL)
, m_persistence(false)
{}

bool IsDigital()
@@ -99,6 +100,9 @@ class WaveformRenderData
int64_t* m_mappedConfigBuffer64;
float* m_mappedFloatConfigBuffer;

//Persistence flags
bool m_persistence;

//Map all buffers for download
void MapBuffers(size_t width, bool update_waveform = true);
void UnmapBuffers(bool update_waveform = true);
@@ -174,7 +178,7 @@ class WaveformArea : public Gtk::GLArea

//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);
static void PrepareGeometry(WaveformRenderData* wdata, bool update_waveform, float alpha, float persistDecay);
void MapAllBuffers(bool update_y);
void UnmapAllBuffers(bool update_y);
void CalculateOverlayPositions();
@@ -186,6 +190,8 @@ class WaveformArea : public Gtk::GLArea

void SyncFontPreferences();

float GetPersistenceDecayCoefficient();

protected:
void SharedCtorInit();

@@ -316,13 +322,6 @@ class WaveformArea : public Gtk::GLArea
VertexBuffer m_colormapVBO;
Program m_colormapProgram;

//Persistence
void RenderPersistenceOverlay();
void InitializePersistencePass();
Program m_persistProgram;
VertexArray m_persistVAO;
VertexBuffer m_persistVBO;

//Eye pattern rendering
void RenderEye();
void InitializeEyePass();
60 changes: 27 additions & 33 deletions src/glscopeclient/WaveformArea_rendering.cpp
Original file line number Diff line number Diff line change
@@ -86,7 +86,7 @@ void WaveformRenderData::MapBuffers(size_t width, bool update_waveform)
}

m_mappedIndexBuffer = (uint32_t*)m_waveformIndexBuffer.Map(width*sizeof(uint32_t));
m_mappedConfigBuffer = (uint32_t*)m_waveformConfigBuffer.Map(sizeof(float)*11);
m_mappedConfigBuffer = (uint32_t*)m_waveformConfigBuffer.Map(sizeof(float)*12);
//We're writing to different offsets in the buffer, not reinterpreting, so this is safe.
//A struct is probably the better long term solution...
//cppcheck-suppress invalidPointerCast
@@ -108,7 +108,7 @@ void WaveformRenderData::UnmapBuffers(bool update_waveform)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Rendering

void WaveformArea::PrepareGeometry(WaveformRenderData* wdata, bool update_waveform, float alpha)
void WaveformArea::PrepareGeometry(WaveformRenderData* wdata, bool update_waveform, float alpha, float persistDecay)
{
//We need analog or digital data to render
auto channel = wdata->m_channel.m_channel;
@@ -215,6 +215,12 @@ void WaveformArea::PrepareGeometry(WaveformRenderData* wdata, bool update_wavefo
wdata->m_mappedFloatConfigBuffer[9] = yscale; //yscale
wdata->m_mappedFloatConfigBuffer[10] = channel->GetOffset(); //yoff

//persistScale
if(!wdata->m_persistence)
wdata->m_mappedFloatConfigBuffer[11] = 0;
else
wdata->m_mappedFloatConfigBuffer[11] = persistDecay;

//Done
wdata->m_geometryOK = true;
}
@@ -272,8 +278,11 @@ void WaveformArea::ResetTextureFiltering()
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}

void WaveformArea::GetAllRenderData(std::vector<WaveformRenderData*>& data)
void WaveformArea::GetAllRenderData(vector<WaveformRenderData*>& data)
{
bool persist = m_persistence && !m_persistenceClear;
m_waveformRenderData->m_persistence = persist;

if(IsAnalog() || IsDigital())
data.push_back(m_waveformRenderData);

@@ -292,6 +301,7 @@ void WaveformArea::GetAllRenderData(std::vector<WaveformRenderData*>& data)
m_overlayRenderData[overlay] = new WaveformRenderData(overlay, this);
m_geometryDirty = true;
}
m_overlayRenderData[overlay]->m_persistence = persist;

data.push_back(m_overlayRenderData[overlay]);
}
@@ -333,6 +343,15 @@ void WaveformArea::UnmapAllBuffers(bool update_y)
}
}

float WaveformArea::GetPersistenceDecayCoefficient()
{
float f = m_parent->GetPreferences().GetReal("Appearance.Waveforms.persist_decay_rate");
f = min(f, 1.0f);
f = max(f, 0.0f);

return f;
}

bool WaveformArea::on_render(const Glib::RefPtr<Gdk::GLContext>& /*context*/)
{
//If a file load is in progress don't waste time on expensive render calls.
@@ -351,6 +370,7 @@ bool WaveformArea::on_render(const Glib::RefPtr<Gdk::GLContext>& /*context*/)
m_pixelsPerVolt = m_height / m_channel.m_channel->GetVoltageRange();

//Update geometry if needed
float persistDecay = GetPersistenceDecayCoefficient();
if(m_geometryDirty || m_positionDirty)
{
double alpha = m_parent->GetTraceAlpha();
@@ -362,7 +382,7 @@ bool WaveformArea::on_render(const Glib::RefPtr<Gdk::GLContext>& /*context*/)
//Do the actual update
MapAllBuffers(m_geometryDirty);
for(auto d : data)
PrepareGeometry(d, m_geometryDirty, alpha);
PrepareGeometry(d, m_geometryDirty, alpha, persistDecay);
UnmapAllBuffers(m_geometryDirty);

m_geometryDirty = false;
@@ -381,17 +401,6 @@ bool WaveformArea::on_render(const Glib::RefPtr<Gdk::GLContext>& /*context*/)
m_firstFrame = false;
}

//TODO: Do persistence processing

/*
if(!m_persistence || m_persistenceClear)
{
m_persistenceClear = false;
}
else
RenderPersistenceOverlay();
*/

//Draw the main waveform
if(IsAnalog() || IsDigital() )
RenderTrace(m_waveformRenderData);
@@ -450,6 +459,9 @@ bool WaveformArea::on_render(const Glib::RefPtr<Gdk::GLContext>& /*context*/)
set_size_request(30, height);
}

//Done, not clearing persistence
m_persistenceClear = false;

return true;
}

@@ -544,24 +556,6 @@ void WaveformArea::RenderWaterfall()
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}

void WaveformArea::RenderPersistenceOverlay()
{
/*
m_waveformFramebuffer.Bind(GL_FRAMEBUFFER);
//Configure blending
glEnable(GL_BLEND);
glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA);
glBlendColor(0, 0, 0, 0.01);
glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
//Draw a black overlay with a little bit of alpha (to make old traces decay)
m_persistProgram.Bind();
m_persistVAO.Bind();
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
*/
}

void WaveformArea::RenderTrace(WaveformRenderData* data)
{
if(!data->m_geometryOK)
12 changes: 0 additions & 12 deletions src/glscopeclient/shaders/persist-fragment.glsl

This file was deleted.

8 changes: 0 additions & 8 deletions src/glscopeclient/shaders/persist-vertex.glsl

This file was deleted.

12 changes: 11 additions & 1 deletion src/glscopeclient/shaders/waveform-compute-analog-noint64.glsl
Original file line number Diff line number Diff line change
@@ -63,6 +63,7 @@ layout(std430, binding=2) buffer config
float ybase;
float yscale;
float yoff;
float persistScale;
};

//Indexes so we know which samples go to which X pixel range
@@ -132,10 +133,19 @@ void main()
return;

//Clear column to blank in the first thread of the block
//(unless doing persistence)
if(gl_LocalInvocationID.y == 0)
{
for(uint y=0; y<windowHeight; y++)
g_workingBuffer[gl_LocalInvocationID.x][y] = 0;
{
if(persistScale == 0)
g_workingBuffer[gl_LocalInvocationID.x][y] = 0;
else
{
vec4 rgba = imageLoad(outputTex, ivec2(gl_GlobalInvocationID.x, y));
g_workingBuffer[gl_LocalInvocationID.x][y] = rgba.a * persistScale;
}
}
}
barrier();
memoryBarrierShared();
12 changes: 11 additions & 1 deletion src/glscopeclient/shaders/waveform-compute-analog.glsl
Original file line number Diff line number Diff line change
@@ -27,6 +27,7 @@ layout(std430, binding=2) buffer config
float ybase;
float yscale;
float yoff;
float persistScale;
};

//Indexes so we know which samples go to which X pixel range
@@ -74,10 +75,19 @@ void main()
return;

//Clear column to blank in the first thread of the block
//(unless doing persistence)
if(gl_LocalInvocationID.y == 0)
{
for(uint y=0; y<windowHeight; y++)
g_workingBuffer[gl_LocalInvocationID.x][y] = 0;
{
if(persistScale == 0)
g_workingBuffer[gl_LocalInvocationID.x][y] = 0;
else
{
vec4 rgba = imageLoad(outputTex, ivec2(gl_GlobalInvocationID.x, y));
g_workingBuffer[gl_LocalInvocationID.x][y] = rgba.a * persistScale;
}
}
}
barrier();
memoryBarrierShared();