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 protected])
>
> 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:
> https://lists.apple.com/mailman/options/cocoa-dev/zav%40mac.com
>
> This email sent to [email protected]
_______________________________________________
Cocoa-dev mailing list ([email protected])
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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com
This email sent to [email protected]