OSX: GUI slows down on renoise.app():show_status() calls

I guess I’ll try to fix this issue in my code base, too. My solution would be simple:

  1. Add a new global FaderPort:showStatus() Function and add a new “on/off preference parameter for status messages”

  2. Only call the real showStatus() Function if message content changes (actually Renoise should do this already ?)

  3. Improve display of fader values etc. Tracking massive values changes with status messages is probably the main problem.

… till then I suggest, like taktik to “out-comment” the LUA API showStatus() calls in FaderPort code.

Hey airmann,

already temp-fixed that by outputting the values using a “timeout-thread” (see faderport thread). If a new value appears the delayed thread will be restarted, to ensure the most recent value will be displayed and the output frequency never crosses the frequency of the delay. This works for now, but is only a workaround.

I think you shouldn’t have to care about slowing down the gui, just by outputting a status message. I would also say, this is gui-related conceptional issue as I wrote above. So do not add this to your faderport source, let’s wait, what taktik will improve there. What do you think? Ok, a global status output function would help for organization, I only delayed two functions which include the status call.

Hey taktik,

the function

renoise.tool():add_menu_entry()

seems to be very, very slow, too - maybe for the same reason like above? Gui is updating on every menu adding?

this test script will take song long that execution will be broken up, although this are “only” 5000 menu entries:

for root = 1,1000 do
      renoise.tool():add_menu_entry {
        name = "Mixer:speedtest:".."bla"..root,
        invoke = function() end
        }
      renoise.tool():add_menu_entry {
        name = "Mixer:speedtest2:".."bla"..root,
        invoke = function() end
        }
      renoise.tool():add_menu_entry {
        name = "Mixer:speedtest3:".."bla"..root,
        invoke = function() end
        }
      renoise.tool():add_menu_entry {
        name = "Mixer:speedtest4:".."bla"..root,
        invoke = function() end
        }
      renoise.tool():add_menu_entry {
        name = "Mixer:speedtest5:".."bla"..root,
        invoke = function() end
        }
     end

Is it possible to fix / speed-up this, too?

Thanks!

Hey airmann,

already temp-fixed that by outputting the values using a “timeout-thread” (see faderport thread). If a new value appears the delayed thread will be restarted, to ensure the most recent value will be displayed and the output frequency never crosses the frequency of the delay. This works for now, but is only a workaround.

I think you shouldn’t have to care about slowing down the gui, just by outputting a status message. I would also say, this is gui-related conceptional issue as I wrote above. So do not add this to your faderport source, let’s wait, what taktik will improve there. What do you think? Ok, a global status output function would help for organization, I only delayed two functions which include the status call.

Sorry, failed to answer earlier :-/.

Yes. I think we wait until taktik will come up with a fix. Otherwise there’s still the possibility to simply switch off the status messages with a little code fix.

Yes. I think we wait until taktik will come up with a fix. Otherwise there’s still the possibility to simply switch off the status messages with a little code fix.

This is hard to fix here. Statusbar messages do, unlike nay other changes in the UI, ask the OS to immediately refresh/redraw the window’s content, so the content is instantly visible. This is done so that one can show progress of lengthy operations in the GUI that happen within one frame. On Linux and Windows thisrefresh is pretty efficient. On OSX it is, as shown here, not. Seems that OSX is synchronizing the buffered content from the window with the Windowmanager (and HW), so most of the time is actually spend with waiting. Its this call here: https://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CGContext/#//apple_ref/c/func/CGContextFlush

I’m not aware of a workaround (CGContextSynchonize won’t do an immediate update, but would also delay the update to the next frame - event loop run).

So a “fix” for this, which retains the ability to instantly show the message is pretty hard to realize here (of course not impossible, but hard) and would be needed for OSX only. I’m simply not sure if it’s worth it.

Hey taktik,

maybe this can help?

https://developer.apple.com/library/mac/technotes/tn2133/_index.html

EDIT:

Here is a discussion from Firefox OSX, they had the same problem, but as far as I know the current Firefox perfectly syncs to screen refresh now without any tearing:https://bugzilla.mozilla.org/show_bug.cgi?id=555834

Quote first link:

General recommendations

Flush once per update event.

Consider periodic updates when live resizing and scrolling, and if needed draw lower quality results.

While an application can get the current screen’s refresh rate, the recommendation is to assume a refresh rate of 60 Hz.

Applications in general shouldn’t draw or flush faster than the user can see. Most animations only need a refresh rate of 30 fps, if an animation needs to update more often, then a timer should be used to limit animation rates to the refresh rate or less.

Avoid, if possible, the functions that request an immediate flush to the screen. Applications drawing with Quartz should useCGContextSynchronizerather thanCGContextFlush.

In Cocoa useNSView’ssetNeedsDisplay:to request an update for a view instead of the more immediatedisplay:, and in Carbon’s HIToolBox useHIViewSetNeedsDisplayorHIViewSetNeedsDisplayInRegioninstead of the immediateHIWindowFlush.

If you cannot find a solution here (but I guess there is one), could you build us in such timeout construction with some ms natively, so to ensure, status bar never will be updated more the 60fps for example? I mean doing those workarounds within the scripts is quite annoying. If the status output would be delayed for 1/60 second, I think nobody would care about or actuallyperceive this…

Hey taktik again,

I now added this to Info.plist:

Attachment 5823 not found.

CGDisableCoalescedUpdates -> TRUE / YES (Boolean)

Like described in the link above. It quite improves the problem described in the Faderport / Stuttermode test thing… It’s still not perfect (like the half framerate now, but not 1Hz anymore), but I guess the above link is the right path to go. Maybe you can improve your gui code like described there… ?

The second problem regarding those huge delay while adding menu entries doesn’t seem to get better, so can you improve the speed of menu adding, so tools like ledger’s Vsti From Menu will work properly?

Thank you!

No, that won’t fix anything. As I tried to explain in my previous post is that every call to show_status() will force a refresh of the UI so that you can immediately see the message.

So the best fix would be not doing such “flushes” at all when not necessary. Of course it would be neat if Renoise manages all this automatically for tools, but if dumping out thousands of messages per second to the status bar is too slow, then it maybe simply should be avoided?

Hm, well I wouldn’t see it like this: Wouldn’t it be normal to assume that a function of the Renoise API should be “stable” in any case?

I mean, this workaround with timeout (no clue how to do this in OSX c++) like this pseudocode:

timeout = null

setStatus(txt)

function setStatus(txt) {
 clear timeout
 set timeout with setStatusDelayed(txt), 1000/60 ms
}
function setStatusDelayed(txt) {
 real set status stuff...
}

Sorry, failed to answer earlier :-/.

Yes. I think we wait until taktik will come up with a fix. Otherwise there’s still the possibility to simply switch off the status messages with a little code fix.

Hey Airmann, since it seems there won’t be a fix from host side, should I do the fix now or will you do it?

I would then make a global setstatus() as you suggested and inside this settimeout-with-60hz-workaround. I mean I have no access to your tool on tools page, so I could send it to you?

btw. taktik I also experience this slowdown for example while using any plugin in bridge-mode, any slider move in the vst windows then usually totally slow downs the renoise gui.

So the best fix would be not doing such “flushes” at all when not necessary. Of course it would be neat if Renoise manages all this automatically for tools, but if dumping out thousands of messages per second to the status bar is too slow, then it maybe simply should be avoided?

I agree to that. Especially that it’s never good style to flood the status bar with too many messages.

On the other hand: shouldn’t even a single status update be as efficient as possible ?

@Jurek: regarding “as stable in any case”. I think it’s a matter of perspective. If an interface or mechanism isn’t designed for a specific requirement/task, than IMO it’s the responsibility of the user to not misuse it. E.g. if I use a kitchen knife for cutting trees it will somehow work, but it will take a very long time ;-).

Hey Airmann, since it seems there won’t be a fix from host side, should I do the fix now or will you do it?

I would then make a global setstatus() as you suggested and inside this settimeout-with-60hz-workaround. I mean I have no access to your tool on tools page, so I could send it to you?

btw. taktik I also experience this slowdown for example while using any plugin in bridge-mode, any slider move in the vst windows then usually totally slow downs the renoise gui.

Yes, send me the code. Thanks for your efforts in advance !

No, that won’t fix anything. As I tried to explain in my previous post is that every call to show_status() will force a refresh of the UI so that you can immediately see the message.

So the best fix would be not doing such “flushes” at all when not necessary. Of course it would be neat if Renoise manages all this automatically for tools, but if dumping out thousands of messages per second to the status bar is too slow, then it maybe simply should be avoided?

Taktik, sorry, but I do not understand you here. Your attitude seems to be quitestubborn to me…

Since we endusers use LUA as an abstraction layer, we have no direct access to any GUI drawing/managing methods. It’s like using Javascript in a browser. Now you are telling me that javascript should not change the status bar too quickly (the javascript execution is btw. controlled by the browser), since it then will totally slow down the browser/make it unusable… Well, I can tell you this scenario never would happen, and if so, it would be considered as a serious bug in the browser.

So what if some tools are installed in OSX Renoise and each writing status bar? Of course then there will appear such slowdowns, too, mostly in a short amount, but will happen. We now need to fix every tool that constantly writes status changes? Well, I am quite sure you could fix this (in no time) if you would be open minded here. The question maybe is, why should be the status bar redrawn multiple times at all before the system even refreshes the next frame? To keep messages secret?

Also also explained that these slowdowns do not only appear while writing status bar. It seems to be a conceptual problem in the gui OSX code (just was a guess, how should I know).

I am not interested in annoying you, I am interested in improving Renoise, improving your software to make it an awesome composing experience. And I don’t see that this forum is “flooded” with feature requests. The most ones constantly repeat over and over again in variations - But you do need seem to care about really. Do you often nowadays use your own software for composing? I mean, if a feature request pops up many times and it is even not such kind of “add now a piano roll, make it cubase”, I really do not understand why you seem to care so less about.

And if you would care more about feature requests, a.k.a. give an answer at all, or sort them into categories, set a priority to themetc., they would stop to be repeated all the time.

Sorry, had to comment this. I will now stop to feature request, it seems to be just a loss of energy.

I did know add this status-bar-osx-workaround into the faderport driver. If anybody has a tool with statusbar updates and want to fix it for osx, have a look at the beginning of the faderport.lua. It’s just a timer of 1000/60ms that updates the status bar with the recent status string, only if it has changed. At the termination, the timer has to be stopped of course. This should be globally available at least in a lua lib, but this is only my opinion.

@Jurek: regarding “as stable in any case”. I think it’s a matter of perspective. If an interface or mechanism isn’t designed for a specific requirement/task, than IMO it’s the responsibility of the user to not misuse it. E.g. if I use a kitchen knife for cutting trees it will somehow work, but it will take a very long time ;-).Y

Well it’s more like taktik has a big, fat chainsaw in his garage but don’t want to use it, so it seem to bereasonable not use the kitchen knife anymore or even try to cut the tree.

Jurek: relax. It’s not aconceptual problem in the OSXgui code. I tried to explain why it behaves as it does - it’s slow by design :wink:

And if the performance with "show_status"really is a problem (when dumping out hundred to thousands of messages per second), the are workarounds for tool developers too. There are million different ways of slowing down Renoise with a tool, just like there are million ways of slowing down a browser with javascript.

And no, this forum IS flooded with feature requests. But those requests are all from different individuals with different ways of working, backgrounds and priorities. There is no such list of things that would make Renoise “complete”. There can’t be, because different people are using Renoise in different ways. People are changing too, so what’s important to someone now may no longer be important in a few months. How could we possibly organize this, while also working on actually implementing them in such a small team?

And no, this forum IS flooded with feature requests. But those requests are all from different individuals with different ways of working, backgrounds and priorities. There is no such list of things that would make Renoise “complete”. There can’t be, because different people are using Renoise in different ways. People are changing too, so what’s important to someone now may no longer be important in a few months. How could we possibly organize this, while also working on actually implementing them in such a small team?

So when are you going to address the feature i asked for 7 years ago? I don’t even remember what it was, but i’m shure it was important. :smiley:

Well it’s more like taktik has a big, fat chainsaw in his garage but don’t want to use it, so it seem to bereasonable not use the kitchen knife anymore or even try to cut the tree.

My intention was to point out that any API can be misused in different ways. I’m with taktik here.

But nonetheless I also don’t fully understand the design: why a complete UI refresh ? That seems not to be efficient. Wouldn’t it be possible to write the message directly to low level screen/frame buffer etc. instead ?

And no, this forum IS flooded with feature requests. But those requests are all from different individuals with different ways of working, backgrounds and priorities. There is no such list of things that would make Renoise “complete”. There can’t be, because different people are using Renoise in different ways. People are changing too, so what’s important to someone now may no longer be important in a few months. How could we possibly organize this, while also working on actually implementing them in such a small team?

taktik I understand the problem, and at the end of the day you and your team decide what’s really important and what shall be done.

But obviously there are quite similar requests from a bigger number of people. E.g. a lot of people hope for “wav tracks” since a very long time. To argue that those “wishes” would change quickly is not true, also it is not true that the small number of developers is the reason that those features are not implemented, yet. I guess the true reason is: the developers decided to not implement those features, because other features came in between. E.g. you decided to go the “Renoise as an instrument”-route and created “Redux”.

Also it’s true that there’s nothing like a complete software. But I’d say that there’s a common feature set which is shared among 90% of the DAW’s out there. And unfortunately Renoise still lacks many of those features. Ok, Renoise has a specific focus and isn’t comparable to Cubase etc…, but it is comparable to Ableton and Bitwig,… Don’t understand me wrong: I really love Renoise because it’s so slim and stable and seems to be very well coded. And I always loved (since v1.9) how you tried to limit the features and inherent complexity, But since 3.0 Renoise feels a bit unbalanced : a lot of new complex features for modulation mayhem, but unfortunately less long awaited bread and butter stuff. But who knows ? Maybe the next Renoise Release is a bit more bread and butter again ? :slight_smile:

So, any news regarding the slow GUI?