From ea7520734c0038165c1526c451eca20884f95928 Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Thu, 22 Oct 2015 18:21:47 -0400 Subject: [PATCH] Waterfall init re-ordering for gl context sanity --- src/panel/WaterfallPanel.cpp | 86 +++++++++++++++++++++--------------- src/panel/WaterfallPanel.h | 3 +- 2 files changed, 53 insertions(+), 36 deletions(-) diff --git a/src/panel/WaterfallPanel.cpp b/src/panel/WaterfallPanel.cpp index 4720b4f..0fd2573 100644 --- a/src/panel/WaterfallPanel.cpp +++ b/src/panel/WaterfallPanel.cpp @@ -10,6 +10,7 @@ WaterfallPanel::WaterfallPanel() : GLPanel(), fft_size(0), waterfall_lines(0), w void WaterfallPanel::setup(int fft_size_in, int num_waterfall_lines_in) { waterfall_lines = num_waterfall_lines_in; fft_size = fft_size_in; + lines_buffered.store(0); if (points.size() != fft_size) { points.resize(fft_size); @@ -23,6 +24,8 @@ void WaterfallPanel::setup(int fft_size_in, int num_waterfall_lines_in) { waterfall_ofs[i] = waterfall_lines - 1; } + texInitialized.store(false); + bufferInitialized.store(false); } void WaterfallPanel::refreshTheme() { @@ -52,7 +55,47 @@ void WaterfallPanel::setPoints(std::vector &points) { void WaterfallPanel::step() { int half_fft_size = fft_size / 2; - if (!waterfall[0]) { + if (!bufferInitialized.load()) { + if (waterfall_slice != NULL) { + delete waterfall_slice; + } + waterfall_slice = new unsigned char[half_fft_size]; + bufferInitialized.store(true); + } + + if (!texInitialized.load()) { + return; + } + + if (points.size()) { + for (int j = 0; j < 2; j++) { + for (int i = 0, iMax = half_fft_size; i < iMax; i++) { + float v = points[j * half_fft_size + i]; + + float wv = v < 0 ? 0 : (v > 0.99 ? 0.99 : v); + + waterfall_slice[i] = (unsigned char) floor(wv * 255.0); + } + + int newBufSize = (half_fft_size*lines_buffered.load()+half_fft_size); + if (lineBuffer[j].size() < newBufSize) { + lineBuffer[j].resize(newBufSize); + rLineBuffer[j].resize(newBufSize); + } + memcpy(&(lineBuffer[j][half_fft_size*lines_buffered.load()]), waterfall_slice, sizeof(unsigned char) * half_fft_size); + } + lines_buffered++; + } +} + +void WaterfallPanel::update() { + int half_fft_size = fft_size / 2; + + if (!bufferInitialized.load()) { + return; + } + + if (!texInitialized.load()) { glGenTextures(2, waterfall); unsigned char *waterfall_tex; @@ -73,48 +116,21 @@ void WaterfallPanel::step() { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, half_fft_size, waterfall_lines, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, (GLvoid *) waterfall_tex); } - if (waterfall_slice != NULL) { - delete waterfall_slice; - } - waterfall_slice = new unsigned char[half_fft_size]; - delete[] waterfall_tex; + + texInitialized.store(true); } - if (points.size()) { - for (int j = 0; j < 2; j++) { - for (int i = 0, iMax = half_fft_size; i < iMax; i++) { - float v = points[j * half_fft_size + i]; - - float wv = v < 0 ? 0 : (v > 0.99 ? 0.99 : v); - - waterfall_slice[i] = (unsigned char) floor(wv * 255.0); - } - - int newBufSize = (half_fft_size*lines_buffered+half_fft_size); - if (lineBuffer[j].size() < newBufSize) { - lineBuffer[j].resize(newBufSize); - rLineBuffer[j].resize(newBufSize); - } - memcpy(&(lineBuffer[j][half_fft_size*lines_buffered]), waterfall_slice, sizeof(unsigned char) * half_fft_size); - } - lines_buffered++; - } -} - -void WaterfallPanel::update() { - int half_fft_size = fft_size / 2; - - for (int i = 0; i < lines_buffered; i++) { + for (int i = 0, iMax = lines_buffered.load(); i < iMax; i++) { for (int j = 0; j < 2; j++) { memcpy(&(rLineBuffer[j][i*half_fft_size]), - &(lineBuffer[j][((lines_buffered-1)*half_fft_size)-(i*half_fft_size)]), sizeof(unsigned char) * half_fft_size); + &(lineBuffer[j][((iMax-1)*half_fft_size)-(i*half_fft_size)]), sizeof(unsigned char) * half_fft_size); } } int run_ofs = 0; - while (lines_buffered) { - int run_lines = lines_buffered; + while (lines_buffered.load()) { + int run_lines = lines_buffered.load(); if (run_lines > waterfall_ofs[0]) { run_lines = waterfall_ofs[0]; } @@ -130,7 +146,7 @@ void WaterfallPanel::update() { } } run_ofs += run_lines*half_fft_size; - lines_buffered-=run_lines; + lines_buffered.store(lines_buffered.load()-run_lines); } } diff --git a/src/panel/WaterfallPanel.h b/src/panel/WaterfallPanel.h index faa566a..100960f 100644 --- a/src/panel/WaterfallPanel.h +++ b/src/panel/WaterfallPanel.h @@ -24,7 +24,8 @@ private: unsigned char *waterfall_slice; std::vector lineBuffer[2]; std::vector rLineBuffer[2]; - int lines_buffered; + std::atomic_int lines_buffered; + std::atomic_bool texInitialized, bufferInitialized; ColorTheme *activeTheme; };