Lisp HUG Maillist Archive

What is the "right" way to do animations in CAPI?

I have an output pane on which I want to show a small geometric
animation.  The intention is that the user is just watching during
this animation, so there's no need for interactivity.

(FWIW, this is on Windows, but in the long run I'd like to use a
technique that works equally well on Windows and OS X.)

What I'm doing right now is the following:

A) The output pane uses :DRAW-WITH-BUFFER T and is also backed by my
own buffer to which I'm drawing.  The display callback essentially
just calls COPY-AREA on (a portion of) my buffer.

B) In a loop I'm updating my buffer, then I call INVALIDATE-RECTANGLE
on my pane and then I wait for about 0.02 seconds using
WAIT-PROCESSING-EVENTS.

This works fine and gives me an animation I'm happy with except that
_sometimes_ it hangs at arbitrary points, i.e. the image freezes for a
few fractions of a second and then the animation continues.  From what
I've tried I'm almost 100% percent sure that this is not due to GC.  I
rather suspect I'm somehow misusing CAPI or the Windows message pump
by calling INVALIDATE-RECTANGLE too often or doing some other sin I'm
not aware of.

I've also tried to do the whole thing with a timer instead of B)
above, but there the same thing happens.

Any ideas?  (And sorry if this is a bit vague...)

Thanks,
Edi.

_______________________________________________
Lisp Hug - the mailing list for LispWorks users
lisp-hug@lispworks.com
http://www.lispworks.com/support/lisp-hug.html


Re: What is the "right" way to do animations in CAPI?

Edi,

I know you mentioned trying a timer, but I’ll just note that it’s the best way to go (for others who come across this thread in the future as well). For example:

https://gist.github.com/massung/c6c21662cf87869745e8

I didn’t comment it, but I hope it’s pretty self-explanitory. And it will work on all platforms.

I would concur with your “it’s not GC” speculation. I put together a 2D physics demo using LW a while ago:

http://www.scratchtask.com/download/physics_demo.mov

This isn’t using a C wrapper (aside from OpenGL)… everything being done is 100% Lisp code (quad-tree updates, collision resolution, and rendering). And I can let this run for a *long* time without seeing any hitches or slow-downs. I merely present this as another data-point supporting your “not GC” hypothesis.

Given that, here are some random thoughts:

* The only time I’ve ever run into “hitching” or slow downs during animation code I’ve written is due to breakpoints in the code. It doesn’t matter where the breakpoint is in the codebase (from what I’ve noticed), merely having one active can seriously impact performance - at least on the Mac.

* Are you rendering to your offscreen port in the CAPI pane process? If so, you might be taking long enough to draw that you miss your window of opportunity to copy it to the pane (similar to missing a v-sync). To get around this, use triple buffering: have 2 back buffers that you toggle between - one you render to and the other you blit. Your display callback should blit the one that is “front" as often and as fast as you like while the other (the “back”) is being drawn to in another process. Here’s a triple buffer example of the same animation as the first gist:

https://gist.github.com/massung/48367cb28fc17f606688

Hope this helps,
Jeff M.


On Dec 22, 2014, at 2:44 PM, Edi Weitz <edi@weitz.de> wrote:


I have an output pane on which I want to show a small geometric
animation.  The intention is that the user is just watching during
this animation, so there's no need for interactivity.

(FWIW, this is on Windows, but in the long run I'd like to use a
technique that works equally well on Windows and OS X.)

What I'm doing right now is the following:

A) The output pane uses :DRAW-WITH-BUFFER T and is also backed by my
own buffer to which I'm drawing.  The display callback essentially
just calls COPY-AREA on (a portion of) my buffer.

B) In a loop I'm updating my buffer, then I call INVALIDATE-RECTANGLE
on my pane and then I wait for about 0.02 seconds using
WAIT-PROCESSING-EVENTS.

This works fine and gives me an animation I'm happy with except that
_sometimes_ it hangs at arbitrary points, i.e. the image freezes for a
few fractions of a second and then the animation continues.  From what
I've tried I'm almost 100% percent sure that this is not due to GC.  I
rather suspect I'm somehow misusing CAPI or the Windows message pump
by calling INVALIDATE-RECTANGLE too often or doing some other sin I'm
not aware of.

I've also tried to do the whole thing with a timer instead of B)
above, but there the same thing happens.

Any ideas?  (And sorry if this is a bit vague...)

Thanks,
Edi.

_______________________________________________
Lisp Hug - the mailing list for LispWorks users
lisp-hug@lispworks.com
http://www.lispworks.com/support/lisp-hug.html


Re: What is the "right" way to do animations in CAPI?

Jeffrey,

That was very helpful advice, thanks a lot!  It reminded me that -
which I actually knew from earlier apps but managed to forget - you
should never do too much in the interface process itself.  I've moved
some of the computation to another thread and now everything works
smoothly... :)

Cool physics demo, BTW!

Happy Holidays,
Edi.





On Tue, Dec 23, 2014 at 7:23 AM, Jeffrey Massung <massung@gmail.com> wrote:
> Edi,
>
> I know you mentioned trying a timer, but I’ll just note that it’s the best
> way to go (for others who come across this thread in the future as well).
> For example:
>
> https://gist.github.com/massung/c6c21662cf87869745e8
>
> I didn’t comment it, but I hope it’s pretty self-explanitory. And it will
> work on all platforms.
>
> I would concur with your “it’s not GC” speculation. I put together a 2D
> physics demo using LW a while ago:
>
> http://www.scratchtask.com/download/physics_demo.mov
>
> This isn’t using a C wrapper (aside from OpenGL)… everything being done is
> 100% Lisp code (quad-tree updates, collision resolution, and rendering).. And
> I can let this run for a *long* time without seeing any hitches or
> slow-downs. I merely present this as another data-point supporting your “not
> GC” hypothesis.
>
> Given that, here are some random thoughts:
>
> * The only time I’ve ever run into “hitching” or slow downs during animation
> code I’ve written is due to breakpoints in the code. It doesn’t matter where
> the breakpoint is in the codebase (from what I’ve noticed), merely having
> one active can seriously impact performance - at least on the Mac.
>
> * Are you rendering to your offscreen port in the CAPI pane process? If so,
> you might be taking long enough to draw that you miss your window of
> opportunity to copy it to the pane (similar to missing a v-sync). To get
> around this, use triple buffering: have 2 back buffers that you toggle
> between - one you render to and the other you blit. Your display callback
> should blit the one that is “front" as often and as fast as you like while
> the other (the “back”) is being drawn to in another process. Here’s a triple
> buffer example of the same animation as the first gist:
>
> https://gist.github.com/massung/48367cb28fc17f606688
>
> Hope this helps,
> Jeff M.
>
>
> On Dec 22, 2014, at 2:44 PM, Edi Weitz <edi@weitz.de> wrote:
>
>
> I have an output pane on which I want to show a small geometric
> animation.  The intention is that the user is just watching during
> this animation, so there's no need for interactivity.
>
> (FWIW, this is on Windows, but in the long run I'd like to use a
> technique that works equally well on Windows and OS X.)
>
> What I'm doing right now is the following:
>
> A) The output pane uses :DRAW-WITH-BUFFER T and is also backed by my
> own buffer to which I'm drawing.  The display callback essentially
> just calls COPY-AREA on (a portion of) my buffer.
>
> B) In a loop I'm updating my buffer, then I call INVALIDATE-RECTANGLE
> on my pane and then I wait for about 0.02 seconds using
> WAIT-PROCESSING-EVENTS.
>
> This works fine and gives me an animation I'm happy with except that
> _sometimes_ it hangs at arbitrary points, i.e. the image freezes for a
> few fractions of a second and then the animation continues.  From what
> I've tried I'm almost 100% percent sure that this is not due to GC.  I
> rather suspect I'm somehow misusing CAPI or the Windows message pump
> by calling INVALIDATE-RECTANGLE too often or doing some other sin I'm
> not aware of.
>
> I've also tried to do the whole thing with a timer instead of B)
> above, but there the same thing happens.
>
> Any ideas?  (And sorry if this is a bit vague...)
>
> Thanks,
> Edi.
>
> _______________________________________________
> Lisp Hug - the mailing list for LispWorks users
> lisp-hug@lispworks.com
> http://www.lispworks.com/support/lisp-hug.html
>
>

_______________________________________________
Lisp Hug - the mailing list for LispWorks users
lisp-hug@lispworks.com
http://www.lispworks.com/support/lisp-hug.html


Updated at: 2020-12-10 08:33 UTC