Re: Prioritizing drawing of the important stuff
Re: Prioritizing drawing of the important stuff
- Subject: Re: Prioritizing drawing of the important stuff
- From: Alex Zavatone <email@hidden>
- Date: Sat, 29 Oct 2016 11:47:21 -0500
Using this as a mental exercise, why not make a system that tracks the time it takes to render each image as each one draws and then schedule each item's render interval based on how much time each one needs to render?
Just to throw caution to the wind, for "teh luls" and just to see what happens, set an "interval upon which to render" for each image based on the amount of it takes to complete its own render, wire up your "renderMeCommaStupid" method to itself then hit the on switch and let her rip.
Have each image responsible for its own rendering. Then test the limits to this madness by allocating a metric crapload of images until the performance starts to suck. As a "cheesy and simple stopgap because we don't know any better", have one or two properties in your image renderer manager that are your control limiters, like min time required before another render or your min time required for an update OR desired max updates per global time unit (max FPS).
Now, if that completely sucks things that do not need to be sucked, you can just go mad and have each item that is supposed to be available for its own rendering into a two stage fifo queue (as opposed to a priority based queue).
The first queue would be "things that need to render" and it would have a max amount of "things that can be in the queue". The second queue would be "things which I am actively going to let render", which contain the reference back to the item that has politely asked to render.
When the thing in the second queue actually gets to the point of "whoa, you actually want to let me render now?" What it does is…
actually check "the global overlord setting" for max FPS or whatever you called it - if it passes, proceed to the next step, otherwise return
ask the object manager, "hey, if take the time now and the object's last time it rendered (another property on the object, the timeOfLastRender) is it => the next time it can be updated
if these conditions are not passed, just return
if these conditions are passed, then tell the object, "whatAreYouWaitingForQuestionMarkRenderYourself" and this gets the object to render and store its timeOfLastRender.
While the whatAreYouWaitingForQuestionMarkRenderYourself method is called, it tracks the time to render in a "howLongItFreakingTookToDrawMe" property, which is the essential governor that each object has which allows the frequency of its updates. A self controlling/self regulating system, if you will. Scienticificans call this a homeostatic system, but hopefully this one is better than our US housing loan self regulation and with less dire consequences if it screws up.
Hopefully.
And if this causes a flicker, or if you need a cleaner display, then don't have each item render itself, but have them flagged To render, and then have the overall manager render all of the items into an offscreen bitmap, lock the current representation of the screen, switch out the image behind your current scene, remove the lock, update the screen, then place an exact copy of the thing you just drew on top of that, and use the image behind as the one to swap out at the next render interval. But you don't have to.
Now, how do I know this is not a horribly terrible idea?
Back last century when there was this multimedia tool and engine called Director, and it's "bitmap rendering multimedia engine in a browser" called Shockwave, we had the what you could consider a scripting language based (OO and SmallTalk with HyperTalk or Lua like syntax) single threaded version of we could consider Cocoa is, but without anything past a rudimentary set of a UI framework.
So I built it.
Part of this was writing something to get async animations on a single threaded system that wouldn't run wild and take the system down if the animation system required too much cycles, so I made it self regulating and wrote primitive pseudo threads, The goal was that, "if something's animating, never lock the user out of interacting with the system". And to test that it actually worked, I broke it. By overloading the system, we find its failure point. So, I overloaded the system by animating hundreds to thousands of objects and i ran out of memory before it started sucking. Noting that this was at a time when Macs had processors called G3, their clock speed was between 233 and 700 MHz and if you were lucky, your system had a GB of RAM, if something like worked well then, it certainly will work well now.
Plus, it's fun.
Go crazy. If you have time, give it a shot.
Alex Zavatone
On Oct 29, 2016, at 4:37 AM, Jonathan Taylor wrote:
> Hi all,
>
> This is a bit of a general question, but hopefully people may have some suggestions. I've got some drawing code that synthesizes an image in a window, which will change in response to sliders (e.g. changing the camera perspective). My problem is how to make it so that the redrawing of the image is as responsive as possible as the slider moves.
>
> At the moment I just respond to KVO notifications from the slider by redrawing. This works fairly well. However, after further development work my program is now a bit more complicated. Effectively, I have two images, one of which is expensive to draw and one less so. What I would like is to have the quick-to-draw one update fairly often, and the more expensive one at lower priority. Does anyone have any suggestions about how to achieve this?
>
> Ideally, I would like the quick image to continue to update responsively as the slider moves. I am less bothered about how responsive the slow image is. One way I could do this is to treat it as low priority, either though a low priority GCD thread or through coalescing post-when-idle NSNotifications. My experiments so far, though, suggest that this is a rather binary thing. The low priority thing only really runs when *nothing* else at all is happening. This can lead to a scenario where (as far as I can tell via Instruments) the OS is spending every moment of idle time redrawing a moving slider at some outrageous frequency, making it look ultra-smooth, but not dedicating *any* time at all to doing my low-priority drawing.
>
> So, I think this basically boils down to a question of load balancing. Is there a good way to balance the time my code spends on different drawing activities, making sure all do happen to some extent, but some more often than others? Importantly (and most challengingly I think) this includes UI drawing activities that the OS undertakes on my behalf (which I have less control over).
>
> I fear there is no easy solution to this, but if anyone has any suggestions for things I should look at, that would be really helpful.
>
> Cheers
> Jonny.
> _______________________________________________
>
> Cocoa-dev mailing list (email@hidden)
>
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden