Merge pull request #662 from jpcima/memory-reporting

Memory reporting and display on editor
This commit is contained in:
JP Cimalando 2021-02-24 02:30:17 +01:00 committed by GitHub
commit 55f2281684
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 75 additions and 47 deletions

View file

@ -86,30 +86,30 @@ widget_class mainView {open
class ChevronDropDown class ChevronDropDown
} }
Fl_Box infoVoicesLabel_ { Fl_Box infoVoicesLabel_ {
xywh {260 76 50 25} labelsize 12 align 16 xywh {260 76 40 25} labelsize 12 align 16
class Label class Label
} }
Fl_Box {} { Fl_Box {} {
label {Max:} label {Max:}
xywh {315 76 60 25} labelsize 12 align 24 xywh {315 76 40 25} labelsize 12 align 24
class Label class Label
} }
Fl_Box numVoicesLabel_ { Fl_Box numVoicesLabel_ {
xywh {380 76 35 25} labelsize 12 align 16 xywh {360 76 35 25} labelsize 12 align 16
class Label class Label
} }
Fl_Box {} { Fl_Box {} {
label {Memory:} label {Memory:}
xywh {435 76 60 25} labelsize 12 align 24 xywh {425 76 60 25} labelsize 12 align 24
class Label class Label
} }
Fl_Box memoryLabel_ { Fl_Box memoryLabel_ {selected
xywh {500 76 50 25} labelsize 12 align 16 xywh {490 76 60 25} labelsize 12 align 16
class Label class Label
} }
Fl_Button numVoicesSlider_ { Fl_Button numVoicesSlider_ {
comment {tag=kTagSetNumVoices} comment {tag=kTagSetNumVoices}
xywh {415 80 20 20} labelsize 16 xywh {395 80 20 20} labelsize 16
class ChevronValueDropDown class ChevronValueDropDown
} }
} }
@ -216,7 +216,7 @@ widget_class mainView {open
} {} } {}
} }
} }
Fl_Group {subPanels_[kPanelSettings]} {open selected Fl_Group {subPanels_[kPanelSettings]} {open
xywh {5 109 790 316} xywh {5 109 790 316}
class LogicalGroup class LogicalGroup
} { } {

View file

@ -47,6 +47,8 @@ struct Editor::Impl : EditorController::Receiver, IControlListener {
std::string userFilesDir_; std::string userFilesDir_;
std::string fallbackFilesDir_; std::string fallbackFilesDir_;
SharedPointer<CVSTGUITimer> memQueryTimer_;
enum { enum {
kPanelGeneral, kPanelGeneral,
kPanelControls, kPanelControls,
@ -172,6 +174,7 @@ struct Editor::Impl : EditorController::Receiver, IControlListener {
void updateCCValue(unsigned cc, float value); void updateCCValue(unsigned cc, float value);
void updateCCDefaultValue(unsigned cc, float value); void updateCCDefaultValue(unsigned cc, float value);
void updateCCLabel(unsigned cc, const char* label); void updateCCLabel(unsigned cc, const char* label);
void updateMemoryUsed(uint64_t mem);
// edition of CC by UI // edition of CC by UI
void performCCValueChange(unsigned cc, float value); void performCCValueChange(unsigned cc, float value);
@ -224,6 +227,10 @@ void Editor::open(CFrame& frame)
impl.frame_ = &frame; impl.frame_ = &frame;
frame.addView(impl.mainView_.get()); frame.addView(impl.mainView_.get());
impl.memQueryTimer_ = makeOwned<CVSTGUITimer>([this](CVSTGUITimer*) {
impl_->sendQueuedOSC("/mem/buffers", "", nullptr);
}, 1000, true);
// request the whole Key and CC information // request the whole Key and CC information
impl.sendQueuedOSC("/key/slots", "", nullptr); impl.sendQueuedOSC("/key/slots", "", nullptr);
impl.sendQueuedOSC("/sw/slots", "", nullptr); impl.sendQueuedOSC("/sw/slots", "", nullptr);
@ -236,6 +243,8 @@ void Editor::close()
impl.clearQueuedOSC(); impl.clearQueuedOSC();
impl.memQueryTimer_ = nullptr;
if (impl.frame_) { if (impl.frame_) {
impl.frame_->removeView(impl.mainView_.get(), false); impl.frame_->removeView(impl.mainView_.get(), false);
impl.frame_ = nullptr; impl.frame_ = nullptr;
@ -461,6 +470,9 @@ void Editor::Impl::uiReceiveMessage(const char* path, const char* sig, const sfi
else if (Messages::matchOSC("/cc&/label", path, indices) && !strcmp(sig, "s")) { else if (Messages::matchOSC("/cc&/label", path, indices) && !strcmp(sig, "s")) {
updateCCLabel(indices[0], args[0].s); updateCCLabel(indices[0], args[0].s);
} }
else if (Messages::matchOSC("/mem/buffers", path, indices) && !strcmp(sig, "h")) {
updateMemoryUsed(args[0].h);
}
else { else {
//fprintf(stderr, "Receive unhandled OSC: %s\n", path); //fprintf(stderr, "Receive unhandled OSC: %s\n", path);
} }
@ -1349,6 +1361,27 @@ void Editor::Impl::updateCCLabel(unsigned cc, const char* label)
panel->setControlLabelText(cc, label); panel->setControlLabelText(cc, label);
} }
void Editor::Impl::updateMemoryUsed(uint64_t mem)
{
if (CTextLabel* label = memoryLabel_) {
double value = mem / 1e3;
const char* unit = "kB";
int precision = 0;
if (value >= 1e3) {
value /= 1e3;
unit = "MB";
}
if (value >= 1e3) {
value /= 1e3;
unit = "GB";
precision = 1;
}
char textbuf[128];
snprintf(textbuf, sizeof(textbuf), "%.*f %s", precision, value, unit);
label->setText(textbuf);
}
}
void Editor::Impl::performCCValueChange(unsigned cc, float value) void Editor::Impl::performCCValueChange(unsigned cc, float value)
{ {
// TODO(jpc) CC as parameters and automation // TODO(jpc) CC as parameters and automation

View file

@ -36,20 +36,20 @@ view__8->addView(view__15);
auto* const view__16 = createChevronDropDown(CRect(345, 9, 370, 34), kTagFileOperations, "", kCenterText, 24); auto* const view__16 = createChevronDropDown(CRect(345, 9, 370, 34), kTagFileOperations, "", kCenterText, 24);
fileOperationsMenu_ = view__16; fileOperationsMenu_ = view__16;
view__8->addView(view__16); view__8->addView(view__16);
auto* const view__17 = createLabel(CRect(75, 71, 125, 96), -1, "", kCenterText, 12); auto* const view__17 = createLabel(CRect(75, 71, 115, 96), -1, "", kCenterText, 12);
infoVoicesLabel_ = view__17; infoVoicesLabel_ = view__17;
view__8->addView(view__17); view__8->addView(view__17);
auto* const view__18 = createLabel(CRect(130, 71, 190, 96), -1, "Max:", kRightText, 12); auto* const view__18 = createLabel(CRect(130, 71, 170, 96), -1, "Max:", kRightText, 12);
view__8->addView(view__18); view__8->addView(view__18);
auto* const view__19 = createLabel(CRect(195, 71, 230, 96), -1, "", kCenterText, 12); auto* const view__19 = createLabel(CRect(175, 71, 210, 96), -1, "", kCenterText, 12);
numVoicesLabel_ = view__19; numVoicesLabel_ = view__19;
view__8->addView(view__19); view__8->addView(view__19);
auto* const view__20 = createLabel(CRect(250, 71, 310, 96), -1, "Memory:", kRightText, 12); auto* const view__20 = createLabel(CRect(240, 71, 300, 96), -1, "Memory:", kRightText, 12);
view__8->addView(view__20); view__8->addView(view__20);
auto* const view__21 = createLabel(CRect(315, 71, 365, 96), -1, "", kCenterText, 12); auto* const view__21 = createLabel(CRect(305, 71, 365, 96), -1, "", kCenterText, 12);
memoryLabel_ = view__21; memoryLabel_ = view__21;
view__8->addView(view__21); view__8->addView(view__21);
auto* const view__22 = createChevronValueDropDown(CRect(230, 75, 250, 95), kTagSetNumVoices, "", kCenterText, 16); auto* const view__22 = createChevronValueDropDown(CRect(210, 75, 230, 95), kTagSetNumVoices, "", kCenterText, 16);
numVoicesSlider_ = view__22; numVoicesSlider_ = view__22;
view__8->addView(view__22); view__8->addView(view__22);
auto* const view__23 = createRoundedGroup(CRect(570, 5, 795, 105), -1, "", kCenterText, 14); auto* const view__23 = createRoundedGroup(CRect(570, 5, 795, 105), -1, "", kCenterText, 14);

View file

@ -65,44 +65,32 @@ protected:
} }
public: public:
void newBuffer(int size) noexcept template <class I>
void newBuffer(I size) noexcept
{ {
numBuffers++; ++numBuffers;
bytes.fetch_add(size); bytes.fetch_add(static_cast<size_t>(size));
} }
void bufferResized(int oldSize, int newSize) noexcept template <class I>
void bufferResized(I oldSize, I newSize) noexcept
{ {
bytes.fetch_add(newSize); bytes.fetch_add(static_cast<size_t>(newSize));
bytes.fetch_sub(oldSize); bytes.fetch_sub(static_cast<size_t>(oldSize));
} }
void bufferDeleted(int size) noexcept template <class I>
void bufferDeleted(I size) noexcept
{ {
numBuffers--; --numBuffers;
bytes.fetch_sub(size); bytes.fetch_sub(static_cast<size_t>(size));
} }
void bufferDeleted(size_t size) noexcept size_t getNumBuffers() const noexcept { return numBuffers; }
{ size_t getTotalBytes() const noexcept { return bytes; }
bufferDeleted(static_cast<int>(size));
}
void bufferResized(size_t oldSize, size_t newSize) noexcept
{
bufferResized(static_cast<int>(oldSize), static_cast<int>(newSize));
}
void newBuffer(size_t size) noexcept
{
newBuffer(static_cast<int>(size));
}
int getNumBuffers() const noexcept { return numBuffers; }
int getTotalBytes() const noexcept { return bytes; }
private: private:
std::atomic<int> numBuffers { 0 }; std::atomic<size_t> numBuffers { 0 };
std::atomic<int> bytes { 0 }; std::atomic<size_t> bytes { 0 };
}; };

View file

@ -88,6 +88,13 @@ void sfz::Synth::dispatchMessage(Client& client, int delay, const char* path, co
//---------------------------------------------------------------------- //----------------------------------------------------------------------
MATCH("/mem/buffers", "") {
uint64_t total = BufferCounter::counter().getTotalBytes();
client.receive<'h'>(delay, path, total);
} break;
//----------------------------------------------------------------------
MATCH("/region&/delay", "") { MATCH("/region&/delay", "") {
GET_REGION_OR_BREAK(indices[0]) GET_REGION_OR_BREAK(indices[0])
client.receive<'f'>(delay, path, region.delay); client.receive<'f'>(delay, path, region.delay);

View file

@ -151,13 +151,13 @@ TEST_CASE("[Buffer] Buffer counter")
sfz::BufferCounter& counter = sfz::Buffer<float>::counter(); sfz::BufferCounter& counter = sfz::Buffer<float>::counter();
// handle the eventuality that the buffer counter does not start at zero // handle the eventuality that the buffer counter does not start at zero
const int initialNumBuffers = counter.getNumBuffers(); const size_t initialNumBuffers = counter.getNumBuffers();
const int initialTotalBytes = counter.getTotalBytes(); const size_t initialTotalBytes = counter.getTotalBytes();
auto haveNumBuffers = [&](int n) -> bool { auto haveNumBuffers = [&](size_t n) -> bool {
return n == counter.getNumBuffers() - initialNumBuffers; return n == counter.getNumBuffers() - initialNumBuffers;
}; };
auto haveTotalAllocation = [&](int n) -> bool { auto haveTotalAllocation = [&](size_t n) -> bool {
return n * static_cast<int>(sizeof(float)) == counter.getTotalBytes() - initialTotalBytes; return n * sizeof(float) == counter.getTotalBytes() - initialTotalBytes;
}; };
// create an empty buffer // create an empty buffer