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
}
Fl_Box infoVoicesLabel_ {
xywh {260 76 50 25} labelsize 12 align 16
xywh {260 76 40 25} labelsize 12 align 16
class Label
}
Fl_Box {} {
label {Max:}
xywh {315 76 60 25} labelsize 12 align 24
xywh {315 76 40 25} labelsize 12 align 24
class Label
}
Fl_Box numVoicesLabel_ {
xywh {380 76 35 25} labelsize 12 align 16
xywh {360 76 35 25} labelsize 12 align 16
class Label
}
Fl_Box {} {
label {Memory:}
xywh {435 76 60 25} labelsize 12 align 24
xywh {425 76 60 25} labelsize 12 align 24
class Label
}
Fl_Box memoryLabel_ {
xywh {500 76 50 25} labelsize 12 align 16
Fl_Box memoryLabel_ {selected
xywh {490 76 60 25} labelsize 12 align 16
class Label
}
Fl_Button numVoicesSlider_ {
comment {tag=kTagSetNumVoices}
xywh {415 80 20 20} labelsize 16
xywh {395 80 20 20} labelsize 16
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}
class LogicalGroup
} {

View file

@ -47,6 +47,8 @@ struct Editor::Impl : EditorController::Receiver, IControlListener {
std::string userFilesDir_;
std::string fallbackFilesDir_;
SharedPointer<CVSTGUITimer> memQueryTimer_;
enum {
kPanelGeneral,
kPanelControls,
@ -172,6 +174,7 @@ struct Editor::Impl : EditorController::Receiver, IControlListener {
void updateCCValue(unsigned cc, float value);
void updateCCDefaultValue(unsigned cc, float value);
void updateCCLabel(unsigned cc, const char* label);
void updateMemoryUsed(uint64_t mem);
// edition of CC by UI
void performCCValueChange(unsigned cc, float value);
@ -224,6 +227,10 @@ void Editor::open(CFrame& frame)
impl.frame_ = &frame;
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
impl.sendQueuedOSC("/key/slots", "", nullptr);
impl.sendQueuedOSC("/sw/slots", "", nullptr);
@ -236,6 +243,8 @@ void Editor::close()
impl.clearQueuedOSC();
impl.memQueryTimer_ = nullptr;
if (impl.frame_) {
impl.frame_->removeView(impl.mainView_.get(), false);
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")) {
updateCCLabel(indices[0], args[0].s);
}
else if (Messages::matchOSC("/mem/buffers", path, indices) && !strcmp(sig, "h")) {
updateMemoryUsed(args[0].h);
}
else {
//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);
}
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)
{
// 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);
fileOperationsMenu_ = 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;
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);
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;
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);
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;
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;
view__8->addView(view__22);
auto* const view__23 = createRoundedGroup(CRect(570, 5, 795, 105), -1, "", kCenterText, 14);

View file

@ -65,44 +65,32 @@ protected:
}
public:
void newBuffer(int size) noexcept
template <class I>
void newBuffer(I size) noexcept
{
numBuffers++;
bytes.fetch_add(size);
++numBuffers;
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_sub(oldSize);
bytes.fetch_add(static_cast<size_t>(newSize));
bytes.fetch_sub(static_cast<size_t>(oldSize));
}
void bufferDeleted(int size) noexcept
template <class I>
void bufferDeleted(I size) noexcept
{
numBuffers--;
bytes.fetch_sub(size);
--numBuffers;
bytes.fetch_sub(static_cast<size_t>(size));
}
void bufferDeleted(size_t size) noexcept
{
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; }
size_t getNumBuffers() const noexcept { return numBuffers; }
size_t getTotalBytes() const noexcept { return bytes; }
private:
std::atomic<int> numBuffers { 0 };
std::atomic<int> bytes { 0 };
std::atomic<size_t> numBuffers { 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", "") {
GET_REGION_OR_BREAK(indices[0])
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();
// handle the eventuality that the buffer counter does not start at zero
const int initialNumBuffers = counter.getNumBuffers();
const int initialTotalBytes = counter.getTotalBytes();
auto haveNumBuffers = [&](int n) -> bool {
const size_t initialNumBuffers = counter.getNumBuffers();
const size_t initialTotalBytes = counter.getTotalBytes();
auto haveNumBuffers = [&](size_t n) -> bool {
return n == counter.getNumBuffers() - initialNumBuffers;
};
auto haveTotalAllocation = [&](int n) -> bool {
return n * static_cast<int>(sizeof(float)) == counter.getTotalBytes() - initialTotalBytes;
auto haveTotalAllocation = [&](size_t n) -> bool {
return n * sizeof(float) == counter.getTotalBytes() - initialTotalBytes;
};
// create an empty buffer