Changeset - 29bd9e9a44b0
[Not reviewed]
default
0 2 0
Hasan Yavuz ÖZDERYA - 8 years ago 2017-11-07 06:11:21
hy@ozderya.net
cache bounding rectangle instead of re-calculating at every reading

improves performance significantly for big buffers
2 files changed with 36 insertions and 23 deletions:
0 comments (0 inline, 0 general)
src/framebuffer.cpp
Show inline comments
 
/*
 
  Copyright © 2015 Hasan Yavuz Özderya
 
  Copyright © 2017 Hasan Yavuz Özderya
 

	
 
  This file is part of serialplot.
 

	
 
  serialplot is free software: you can redistribute it and/or modify
 
  it under the terms of the GNU General Public License as published by
 
  the Free Software Foundation, either version 3 of the License, or
 
@@ -22,13 +22,14 @@
 
FrameBuffer::FrameBuffer(size_t size)
 
{
 
    _size = size;
 
    data = new double[_size]();
 
    headIndex = 0;
 

	
 
    _boundingRect.setCoords(0, 0, size, 0);
 
    brInvalid = false;
 
    _brCache.setCoords(0, 0, size, 0);
 
}
 

	
 
FrameBuffer::~FrameBuffer()
 
{
 
    delete[] data;
 
}
 
@@ -60,14 +61,14 @@ void FrameBuffer::resize(size_t size)
 
    // data is ready, clean and re-point
 
    delete data;
 
    data = newData;
 
    headIndex = 0;
 
    _size = size;
 

	
 
    // update the bounding rectangle
 
    _boundingRect.setRight(_size);
 
    // invalidate bounding rectangle
 
    brInvalid = true;
 
}
 

	
 
void FrameBuffer::addSamples(double* samples, size_t size)
 
{
 
    unsigned shift = size;
 
    if (shift < _size)
 
@@ -110,13 +111,36 @@ void FrameBuffer::addSamples(double* sam
 
        {
 
            data[i] = samples[i+x];
 
        }
 
        headIndex = 0;
 
    }
 

	
 
    // update bounding rectangle
 
    // invalidate cache
 
    brInvalid = true;
 
}
 

	
 
void FrameBuffer::clear()
 
{
 
    for (size_t i=0; i < _size; i++) data[i] = 0.;
 

	
 
    _brCache.setCoords(0, 0, _size, 0);
 
}
 

	
 
size_t FrameBuffer::size() const
 
{
 
    return _size;
 
}
 

	
 
QRectF FrameBuffer::boundingRect() const
 
{
 
    if (brInvalid) updateBoundingRect();
 
    return _brCache;
 
}
 

	
 
void FrameBuffer::updateBoundingRect() const
 
{
 
    double minValue = data[0];
 
    double maxValue = data[0];
 
    for (size_t i = 0; i < _size; i++)
 
    {
 
        if (data[i] > maxValue)
 
        {
 
@@ -124,29 +148,16 @@ void FrameBuffer::addSamples(double* sam
 
        }
 
        else if (data[i] < minValue)
 
        {
 
            minValue = data[i];
 
        }
 
    }
 
    _boundingRect.setTop(minValue);
 
    _boundingRect.setBottom(maxValue);
 
}
 

	
 
void FrameBuffer::clear()
 
{
 
    for (size_t i=0; i < _size; i++) data[i] = 0.;
 
}
 
    _brCache.setTop(minValue);
 
    _brCache.setBottom(maxValue);
 

	
 
size_t FrameBuffer::size() const
 
{
 
    return _size;
 
}
 

	
 
QRectF FrameBuffer::boundingRect() const
 
{
 
    return _boundingRect;
 
    brInvalid = false;
 
}
 

	
 
double FrameBuffer::sample(size_t i) const
 
{
 
    size_t index = headIndex + i;
 
    if (index >= _size) index -= _size;
src/framebuffer.h
Show inline comments
 
/*
 
  Copyright © 2015 Hasan Yavuz Özderya
 
  Copyright © 2017 Hasan Yavuz Özderya
 

	
 
  This file is part of serialplot.
 

	
 
  serialplot is free software: you can redistribute it and/or modify
 
  it under the terms of the GNU General Public License as published by
 
  the Free Software Foundation, either version 3 of the License, or
 
@@ -40,10 +40,12 @@ public:
 

	
 
private:
 
    size_t _size; // size of `data`
 
    double* data;
 
    size_t headIndex; // indicates the actual `0` index of the ring buffer
 

	
 
    QRectF _boundingRect;
 
    mutable bool brInvalid; ///< Indicates that bounding rectangle needs to be re-calculated
 
    mutable QRectF _brCache; ///< Cache for boundingRect()
 
    void updateBoundingRect() const; ///< Updates bounding rectangle cache
 
};
 

	
 
#endif // FRAMEBUFFER_H
0 comments (0 inline, 0 general)