From aa6debc040dd312144f62d1809b82db80001310d Mon Sep 17 00:00:00 2001 From: Jakob Voigts <jvoigts@mit.edu> Date: Fri, 19 Feb 2016 11:40:47 -0500 Subject: [PATCH] added update line, fixed redraw() bug, performance tweaks still needs more pointer checks for the pixel drawing when resizing - can still crash fairly easily --- .../LfpDisplayNode/LfpDisplayCanvas.cpp | 98 +++++++++---------- .../Plugins/LfpDisplayNode/LfpDisplayCanvas.h | 2 +- 2 files changed, 47 insertions(+), 53 deletions(-) diff --git a/Source/Plugins/LfpDisplayNode/LfpDisplayCanvas.cpp b/Source/Plugins/LfpDisplayNode/LfpDisplayCanvas.cpp index 0972814af..debfa3385 100644 --- a/Source/Plugins/LfpDisplayNode/LfpDisplayCanvas.cpp +++ b/Source/Plugins/LfpDisplayNode/LfpDisplayCanvas.cpp @@ -732,7 +732,7 @@ void LfpDisplayCanvas::updateScreenBuffer() if (screenBufferIndex[channel] >= maxSamples) // wrap around if we reached right edge before screenBufferIndex.set(channel, 0); - // hold these values locally for each channel + // hold these values locally for each channel - is this a good idea? int sbi = screenBufferIndex[channel]; int dbi = displayBufferIndex[channel]; @@ -1411,12 +1411,8 @@ void LfpDisplay::resized() void LfpDisplay::paint(Graphics& g) { - - - //Graphics gSharedLfpDisplay(lfpChannelBitmap); - //Graphics gBackGround(m_iBackGround); /* ColourGradient grad = ColourGradient(Colours::white,0.f,0.f,Colours::green, (float)lfpChannelBitmap.getWidth(), (float)lfpChannelBitmap.getHeight(), false); @@ -1452,7 +1448,9 @@ void LfpDisplay::refresh() { gLfpChannelBitmap.fillRect(0,0, getWidth(), getHeight()); } else { - gLfpChannelBitmap.fillRect(fillfrom,0, (fillto-fillfrom)+3, getHeight()); + gLfpChannelBitmap.setColour(Colour(0,0,0)); //background color + + gLfpChannelBitmap.fillRect(fillfrom,0, (fillto-fillfrom)+1, getHeight()); }; @@ -1462,7 +1460,7 @@ void LfpDisplay::refresh() int componentTop = channels[i]->getY(); int componentBottom = channels[i]->getHeight() + componentTop; - if ((topBorder <= componentBottom && bottomBorder >= componentTop)) + if ((topBorder <= componentBottom && bottomBorder >= componentTop)) // only draw things that are visible { if (canvas->fullredraw) { @@ -1474,20 +1472,26 @@ void LfpDisplay::refresh() } else { - channels[i]->pxPaint(); - // we redraw from -2 to +1 (px) relative to the real redraw window, the -2 makes sure that the lines join nicely, and the +1 draws the vertical update line + channels[i]->pxPaint(); // draws to lfpChannelBitmap + + // it's not clear why, but apparently because the pxPaint() in a child component of LfpDisplay, we also need to issue repaint() calls for each channel, even though there's nothin to repaint there. Otherwise, the repaint call in LfpDisplay::refresh(), a few lines down, lags behind the update line by ~60 px. This could ahev something to do with teh reopaint message passing in juce. In any case, this seemingly redundant repaint here seems to fix the issue. + + // we redraw from 0 to +2 (px) relative to the real redraw window, the +1 draws the vertical update line + channels[i]->repaint(fillfrom, 0, (fillto-fillfrom)+2, channels[i]->getHeight()); + + } //std::cout << i << std::endl; } } + if (canvas->fullredraw) { - repaint(); + repaint(0,topBorder,getWidth(),bottomBorder-topBorder); }else{ - //repaint(); - repaint(canvas->lastScreenBufferIndex[0]-2, topBorder, (canvas->screenBufferIndex[0]-canvas->lastScreenBufferIndex[0])+3, bottomBorder-topBorder); + repaint(fillfrom, topBorder, (fillto-fillfrom)+1, bottomBorder-topBorder); } canvas->fullredraw = false; @@ -1642,7 +1646,8 @@ void LfpDisplay::mouseWheelMove(const MouseEvent& e, const MouseWheelDetails& } canvas->setRangeSelection(h); // update combobox - + canvas->fullredraw = true; //issue full redraw - scrolling without modifier doesnt require a full redraw + } else // just scroll { @@ -1651,7 +1656,7 @@ void LfpDisplay::mouseWheelMove(const MouseEvent& e, const MouseWheelDetails& viewport->mouseWheelMove(e.getEventRelativeTo(canvas), wheel); } - canvas->fullredraw = true; //issue full redraw - scrolling without modifier doesnt require a full redraw + } //refresh(); // doesn't seem to be needed now that channels daraw to bitmap @@ -1837,13 +1842,26 @@ void LfpChannelDisplay::setEnabledState(bool state) void LfpChannelDisplay::pxPaint() { + if (isEnabled) + { + Image::BitmapData bdLfpChannelBitmap(display->lfpChannelBitmap, 0,0, display->lfpChannelBitmap.getWidth(), display->lfpChannelBitmap.getHeight()); + + int center = getHeight()/2; + int jfrom_wholechannel= (int) (getY()+center-channelHeight/2)+1; + int jto_wholechannel= (int) getY()+center+channelHeight/2; - Image::BitmapData bdLfpChannelBitmap(display->lfpChannelBitmap, 0,0, display->lfpChannelBitmap.getWidth(), display->lfpChannelBitmap.getHeight()); + if (jfrom_wholechannel<0) {jfrom_wholechannel=0;}; + if (jto_wholechannel >= display->lfpChannelBitmap.getHeight()) {jto_wholechannel=display->lfpChannelBitmap.getHeight()-1;}; - if (isEnabled) - { + // draw most recent drawn sample position + for (int k=jfrom_wholechannel; k<=jto_wholechannel; k+=2) // draw line + bdLfpChannelBitmap.setPixelColour(canvas->screenBufferIndex[chan]+1,k, Colours::yellow); + + + // pre compute some colors for later so we dont do it once per pixel. + Colour lineColourBright = lineColour.withMultipliedBrightness(2.0f); + Colour lineColourDark = lineColour.withMultipliedSaturation(0.5f).withMultipliedBrightness(0.3f); - int center = getHeight()/2; int stepSize = 1; int from = 0; // for vertical line drawing in the LFP data @@ -1854,7 +1872,7 @@ void LfpChannelDisplay::pxPaint() if (ifrom < 0) ifrom = 0; - int ito = canvas->screenBufferIndex[chan] - 1; + int ito = canvas->screenBufferIndex[chan] +0; if (fullredraw) { @@ -1887,21 +1905,11 @@ void LfpChannelDisplay::pxPaint() if (rawEventState & (1 << ev_ch)) // events are representet by a bit code, so we have to extract the individual bits with a mask { //std::cout << "Drawing event." << std::endl; - //g.setColour(display->channelColours[ev_ch*2]); // get color from lfp color scheme - //g.setOpacity(0.35f); - //g.drawLine(i, center-channelHeight/2 , i, center+channelHeight/2); - Colour currentcolor=display->channelColours[ev_ch*2]; - int jfrom= (int) (getY()+center-channelHeight/2)+1; - int jto= (int) getY()+center+channelHeight/2; - if (jfrom<0) {jfrom=0;}; - if (jto >= display->lfpChannelBitmap.getHeight()) {jto=display->lfpChannelBitmap.getHeight()-1;}; - - for (int k=jfrom; k<=jto; k++) // draw line - { + for (int k=jfrom_wholechannel; k<=jto_wholechannel; k++) // draw line bdLfpChannelBitmap.setPixelColour(i,k,bdLfpChannelBitmap.getPixelColour(i,k).interpolatedWith(currentcolor,0.3f)); - } + } } } @@ -1943,24 +1951,15 @@ void LfpChannelDisplay::pxPaint() float rangeHist[samplerange]; // paired range histogram, same as plotting at higher res. and subsampling for (int k=0; k<=samplerange; k++) - { - //localHist[k]=0; rangeHist[k]=0; - } - + - //for (int k=0; k<=sampleCountThisPixel; k++) // add up simple histogram - //{ - // int cs = (((samplesThisPixel[k]/range*channelHeightFloat)+getHeight()/2)-from); - // if (cs<0) {cs=0;}; - // if (cs>samplerange) {cs=samplerange;}; - // localHist[cs]++; - // } + for (int k=0; k<=sampleCountThisPixel; k++) // add up paired-range histogram per pixel - for each pair fill intermediate with uniform distr. { - int cs_this = (((samplesThisPixel[k]/range*channelHeightFloat)+getHeight()/2)-from); // sample values -> pixel coordinates relative to from + int cs_this = (((samplesThisPixel[k]/range*channelHeightFloat)+getHeight()/2)-from); // sample values -> pixel coordinates relative to from int cs_next = (((samplesThisPixel[k+1]/range*channelHeightFloat)+getHeight()/2)-from); @@ -1998,9 +1997,9 @@ void LfpChannelDisplay::pxPaint() if (a>1.0f) {a=1.0f;}; if (a<0.0f) {a=0.0f;}; - - Colour gradedColor = lineColour.withMultipliedBrightness(2.0f).interpolatedWith(lineColour.withMultipliedSaturation(0.6f).withMultipliedBrightness(0.3f),1-a) ; - //Colour gradedColor = Colour(0,0,0).interpolatedWith(Colour(255,255,255),a); + + //Colour gradedColor = lineColour.withMultipliedBrightness(2.0f).interpolatedWith(lineColour.withMultipliedSaturation(0.6f).withMultipliedBrightness(0.3f),1-a) ; + Colour gradedColor = lineColourBright.interpolatedWith(lineColourDark,1-a); //Colour gradedColor = Colour(0,255,0); int ploty = from+s+getY(); @@ -2035,7 +2034,7 @@ void LfpChannelDisplay::pxPaint() if (jto >= display->lfpChannelBitmap.getHeight()) {jto=display->lfpChannelBitmap.getHeight()-1;}; - for (int j = jfrom; j <= jto; j += 1) + for (int j = jfrom; j <= jto; j += 1) { //uint8* const pu8Pixel = bdSharedLfpDisplay.getPixelPointer( (int)(i),(int)(j)); @@ -2053,11 +2052,6 @@ void LfpChannelDisplay::pxPaint() } - // g.setColour(lineColour.withAlpha(0.7f)); // alpha on seems to decrease draw speed - // g.setFont(channelFont); - // g.setFont(channelHeightFloat*0.6); - - // g.drawText(String(chan+1), 10, center-channelHeight/2, 200, channelHeight, Justification::left, false); } diff --git a/Source/Plugins/LfpDisplayNode/LfpDisplayCanvas.h b/Source/Plugins/LfpDisplayNode/LfpDisplayCanvas.h index 6f6d00d58..41e31d959 100644 --- a/Source/Plugins/LfpDisplayNode/LfpDisplayCanvas.h +++ b/Source/Plugins/LfpDisplayNode/LfpDisplayCanvas.h @@ -135,7 +135,7 @@ private: static const int MAX_N_CHAN = 2048; // maximum number of channels static const int MAX_N_SAMP = 5000; // maximum display size in pixels - static const int MAX_N_SAMP_PER_PIXEL = 500; // maximum samples considered for drawing each pixel + static const int MAX_N_SAMP_PER_PIXEL = 200; // maximum samples considered for drawing each pixel //float waves[MAX_N_CHAN][MAX_N_SAMP*2]; // we need an x and y point for each sample LfpDisplayNode* processor; -- GitLab