Smooth Animation by Synching to the Raster

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

Smooth Animation by Synching to the Raster

Runar Jordahl
I try to render smooth animation using an off-screen Pixmap, which I
use to draw my graphics on. Once the pixmap is ready, I use "pixmap
displayOn: window graphicsContext" to put the pixmap on the screen. As
described by Sam
(http://www.cincomsmalltalk.com/userblogs/pollock/blogView?showComments=true&entry=3242908973),
I am "unlucky" and visible "glitches" are shown during screen update.
This is caused by the raster sometimes being in the middle of the
section of the screen I start updating.

I am looking for a way to wait for the raster being at the top of the
screen, and then start my display of the pixmap. Something like the
following:

self waitForRasterToStartAtTopOfScreen.
pixmap displayOn: window graphicsContext

If #displayOn: is moving faster downwards the screen than the raster,
I should be fine.

Now, I am not sure whether what I outline above is the correct
solution to my problem. Maybe there is no solution easily available. I
tried looking into WarpBlt, but could not get it working. Could this
parcel help me in any way?

Runar Jordahl

Reply | Threaded
Open this post in threaded view
|

Re: Smooth Animation by Synching to the Raster

Alan Knight-2
I doubt that WarpBlit would help you. Probably you would need to interface to something like DirectX or OpenGL to get those kind of capabilities. Nowadays I doubt that this is of so much importance anyway, since there are so many fewer CRT screens. I have 5 computers here, and none of them have a raster to synchronize with.

At 09:49 AM 3/30/2006, Runar Jordahl wrote:

>I try to render smooth animation using an off-screen Pixmap, which I
>use to draw my graphics on. Once the pixmap is ready, I use "pixmap
>displayOn: window graphicsContext" to put the pixmap on the screen. As
>described by Sam
>(http://www.cincomsmalltalk.com/userblogs/pollock/blogView?showComments=true&entry=3242908973),
>I am "unlucky" and visible "glitches" are shown during screen update.
>This is caused by the raster sometimes being in the middle of the
>section of the screen I start updating.
>
>I am looking for a way to wait for the raster being at the top of the
>screen, and then start my display of the pixmap. Something like the
>following:
>
>self waitForRasterToStartAtTopOfScreen.
>pixmap displayOn: window graphicsContext
>
>If #displayOn: is moving faster downwards the screen than the raster,
>I should be fine.
>
>Now, I am not sure whether what I outline above is the correct
>solution to my problem. Maybe there is no solution easily available. I
>tried looking into WarpBlt, but could not get it working. Could this
>parcel help me in any way?
>
>Runar Jordahl

--
Alan Knight [|], Cincom Smalltalk Development
[hidden email]
[hidden email]
http://www.cincom.com/smalltalk

"The Static Typing Philosophy: Make it fast. Make it right. Make it run." - Niall Ross

Reply | Threaded
Open this post in threaded view
|

Re: Smooth Animation by Synching to the Raster

Reinout Heeck
Alan Knight wrote:
> I doubt that WarpBlit would help you. Probably you would need to interface
> to something like DirectX or OpenGL to get those kind of capabilities.
> Nowadays I doubt that this is of so much importance anyway, since there are
> so many fewer CRT screens. I have 5 computers here, and none of them have a
> raster to synchronize with.

I think this is a misguided answer.
Modern screens still get their data serially (line-byline, left-to-right), so
the same problems still apply. Even if modern monitors buffer an entire frame
(I have no idea whether they do this) the synchronization issues exist on the
graphics-card end of affairs: if the card is busy sending lines to the
monitor in an area that the pixmap is being copied to at that same time you
get odd 'half pictures' being stacked on top of each other. If the copying of
the pixmap is not synchronized to the monitor's frame rate that division line
will move vertically (showing the interference between the monitor's refresh
frequency and the frequency of pixmap copying). Since monitors have higher
frame rates these days the problem my well be worse than in the old
'everything is 30Hz' days.


Bottom line is still that VisualWorks does not directly support this kind of
synchronization, as Alan suggests you will need to hook up to some external
library that provides such a synchronization service (either by synching your
St execution thread, or by doing the pixmap copying on behalf of the VM).



HTH,

Reinout
-------

Reply | Threaded
Open this post in threaded view
|

Re: Smooth Animation by Synching to the Raster

Roland Wagener
In reply to this post by Runar Jordahl
Hello Runar

I havent looked at the Pollock-Blog, but I have done some picture/pixmap
display stuff in the past, and the only available means to avoid flicker
artefacts is to use the DoubleBufferingWindowDisplayPolicy. For an
example look at:
        MacOSXProgressWidgetView class progressOpenOn:label:

Where just one window is initialized to use this special setup.

Greetings

Roland Wagener
--
Senior Consultant at Georg Heeg eK
VisualWorks Ambassador
phone: x49-231-9 75 99-0       fax: x49-231-9 75 99-20
email: [hidden email]          www: http://www.heeg.de/~roland


Runar Jordahl schrieb:

> I try to render smooth animation using an off-screen Pixmap, which I
> use to draw my graphics on. Once the pixmap is ready, I use "pixmap
> displayOn: window graphicsContext" to put the pixmap on the screen. As
> described by Sam
> (http://www.cincomsmalltalk.com/userblogs/pollock/blogView?showComments=true&entry=3242908973),
> I am "unlucky" and visible "glitches" are shown during screen update.
> This is caused by the raster sometimes being in the middle of the
> section of the screen I start updating.
>
> I am looking for a way to wait for the raster being at the top of the
> screen, and then start my display of the pixmap. Something like the
> following:
>
> self waitForRasterToStartAtTopOfScreen.
> pixmap displayOn: window graphicsContext
>
> If #displayOn: is moving faster downwards the screen than the raster,
> I should be fine.
>
> Now, I am not sure whether what I outline above is the correct
> solution to my problem. Maybe there is no solution easily available. I
> tried looking into WarpBlt, but could not get it working. Could this
> parcel help me in any way?
>
> Runar Jordahl
>
>

Reply | Threaded
Open this post in threaded view
|

Re: Smooth Animation by Synching to the Raster

Runar Jordahl
Even if double buffering is used, you get the problem I describe. As
Reinout explained: "(...) if the card is busy sending lines to the
monitor in an area that the pixmap is being copied to at that same
time you get odd 'half pictures' being stacked on top of each other."
So the problem happens when the buffer is copied to the screen.

This problem will typically only happen for "smooth" animation.

A progress bar, which usually has a horizontal layout, is not that
vulnerable to this problem. It gets worse when the height if the
updated region increases. Below I attach a small script showing an
example. The vertical bar gets flicker on its sides when it moves over
the screen.

| pixmap image window |
image := Image extent: (20@350) depth: 24 palette: FixedPalette rgb8Bit.
image pixelsDo: [:x :y | image atPoint: (x@y) put: 0].
window := ApplicationWindow openNewIn: (10 @ 10 extent: 1000 @ 700).
1 to: 400 do: [: i |
        pixmap := Pixmap extent: (1000@700) on: Screen default.
        image displayOn: pixmap graphicsContext at: i@i.
        pixmap displayOn: window graphicsContext].
 window close

Runar Jordahl

Reply | Threaded
Open this post in threaded view
|

RE: Smooth Animation by Synching to the Raster

Steven Kelly
In reply to this post by Runar Jordahl
From: Runar Jordahl [mailto:[hidden email]]
> Below I attach a small script showing an example.
> The vertical bar gets flicker on its sides when it
> moves over the screen.
>
> | pixmap image window |
> image := Image extent: (20@350) depth: 24 palette: FixedPalette
rgb8Bit.
> image pixelsDo: [:x :y | image atPoint: (x@y) put: 0].
> window := ApplicationWindow openNewIn: (10 @ 10 extent: 1000 @ 700).
> 1 to: 400 do: [: i |
> pixmap := Pixmap extent: (1000@700) on: Screen default.
> image displayOn: pixmap graphicsContext at: i@i.
> pixmap displayOn: window graphicsContext].
>  window close

I don't see that problem (21" CRT, 1600x1200 @ 75Hz). I may _just_ be
able to see some slight roughening of the edge on occasion, which could
be what you mean. I suppose a one pixel error isn't much given the
rather fuzzy definition on CRTs at this kind of resolution.

Trying again with (1 to: 400 by: 5) clearly shows the problem. Still,
that's something to be aware of: if the animation is only moving by a
pixel at a time, the problem may not be serious. I have serious doubts
that the lack of refresh synch Sames refers to in his blog is a major
part of the flickering problem in Wrapper.

One problem I did see in the animation was a clear jerk in the motion
every half a second or so. This was presumably because the code created
a new Pixmap on each iteration, so there's a lot of garbage collection.
I disabled gc, and the jerking indeed disappears. Moving the Pixmap
creation outside the block, and just clearing it inside the block,
helps, and also makes things much faster (3x?). No problem - I know you
weren't aiming for high performance code, but at least on my display the
effect you were trying to show was hardly visible, and the jerking was a
clear problem - interesting how hard it is sometimes to demonstrate
these kinds of performance issues!

Steve

Reply | Threaded
Open this post in threaded view
|

Re: Smooth Animation by Synching to the Raster

Runar Jordahl
I agree  -- even showing such problems can be hard. Here is the
example updated according to your advises:

| pixmap image window |
image := Image extent: (20@350) depth: 24 palette: FixedPalette rgb8Bit.
image pixelsDo: [:x :y | image atPoint: (x@y) put: 0].
window := ApplicationWindow openNewIn: (10 @ 10 extent: 1000 @ 700).
pixmap := Pixmap extent: (1000@700) on: Screen default.
(1 to: 1000 by: 3) do: [: i |
        image displayOn: pixmap graphicsContext at: i@i.
        pixmap displayOn: window graphicsContext.
        pixmap clear].
 window close

Runar

Reply | Threaded
Open this post in threaded view
|

RE: Smooth Animation by Synching to the Raster

Stew MacLean
In reply to this post by Runar Jordahl
Hi Runar,

I tried this in 7.2, but rgb8Bit is missing.

Is this a base method?

Thanks,

Stewart

>-----Original Message-----
>From: Runar Jordahl [mailto:[hidden email]]
>Sent: Friday, 31 March 2006 8:22 p.m.
>To: Roland Wagener
>Cc: VWNC
>Subject: Re: Smooth Animation by Synching to the Raster
>
>Even if double buffering is used, you get the problem I describe. As
>Reinout explained: "(...) if the card is busy sending lines to the
>monitor in an area that the pixmap is being copied to at that same
>time you get odd 'half pictures' being stacked on top of each other."
>So the problem happens when the buffer is copied to the screen.
>
>This problem will typically only happen for "smooth" animation.
>
>A progress bar, which usually has a horizontal layout, is not that
>vulnerable to this problem. It gets worse when the height if the
>updated region increases. Below I attach a small script showing an
>example. The vertical bar gets flicker on its sides when it moves over
>the screen.
>
>| pixmap image window |
>image := Image extent: (20@350) depth: 24 palette: FixedPalette
rgb8Bit.
>image pixelsDo: [:x :y | image atPoint: (x@y) put: 0].
>window := ApplicationWindow openNewIn: (10 @ 10 extent: 1000 @ 700).
>1 to: 400 do: [: i |
> pixmap := Pixmap extent: (1000@700) on: Screen default.
> image displayOn: pixmap graphicsContext at: i@i.
> pixmap displayOn: window graphicsContext].
> window close
>
>Runar Jordahl



Reply | Threaded
Open this post in threaded view
|

Re: Smooth Animation by Synching to the Raster

Runar Jordahl
Yes, it is in the base. Defined in package "Graphics-Palettes".

Below is the script modified to work in 7.2. Note that it performs
faster since the image now has less data (monocolor). It still has the
same problem.

| pixmap image window |
image := Image extent: (20@350) depth: 1 palette: MappedPalette blackWhite.
image pixelsDo: [:x :y | image atPoint: (x@y) put: 0].
window := ApplicationWindow openNewIn: (10 @ 10 extent: 1000 @ 700).

pixmap := Pixmap extent: (1000@700) on: Screen default.

(1 to: 1000 by: 1) do: [: i |

       image displayOn: pixmap graphicsContext at: i@i.

       pixmap displayOn: window graphicsContext.
       pixmap clear].
 window close


Runar Jordahl

Reply | Threaded
Open this post in threaded view
|

RE: Smooth Animation by Synching to the Raster

Stew MacLean
I changed the loop to (1 to: 400 by: 5), as suggested by Steve, and
wrapped a repeat around it.

On my screen, (21" 1600*1200 85Hz), I can visibly see both vertical
edges "breaking up", and the "break up" appears to move up the image (ie
it seems concentrated in one (or sometimes more), randomly varying,
sections of the screen.

HTH,

Stewart

>-----Original Message-----
>From: Runar Jordahl [mailto:[hidden email]]
>Sent: Monday, 3 April 2006 8:38 p.m.
>To: Stewart MacLean
>Cc: Roland Wagener; VWNC
>Subject: Re: Smooth Animation by Synching to the Raster
>
>Yes, it is in the base. Defined in package "Graphics-Palettes".
>
>Below is the script modified to work in 7.2. Note that it performs
>faster since the image now has less data (monocolor). It still has the
>same problem.
>
>| pixmap image window |
>image := Image extent: (20@350) depth: 1 palette: MappedPalette
blackWhite.

>image pixelsDo: [:x :y | image atPoint: (x@y) put: 0].
>window := ApplicationWindow openNewIn: (10 @ 10 extent: 1000 @ 700).
>
>pixmap := Pixmap extent: (1000@700) on: Screen default.
>
>(1 to: 1000 by: 1) do: [: i |
>
>       image displayOn: pixmap graphicsContext at: i@i.
>
>       pixmap displayOn: window graphicsContext.
>       pixmap clear].
> window close
>
>
>Runar Jordahl



Reply | Threaded
Open this post in threaded view
|

Re: Smooth Animation by Synching to the Raster

Vassili Bykov
In reply to this post by Stew MacLean
Stewart MacLean wrote:
> Hi Runar,
>
> I tried this in 7.2, but rgb8Bit is missing.
>
> Is this a base method?
>

We added #rgb8bit relatively recently, if I remember correctly in 7.3.

--
Vassili Bykov <[hidden email]>

[:s | s, s printString] value: '[s: | s, s printString] value: '

Reply | Threaded
Open this post in threaded view
|

Re: Smooth Animation by Synching to the Raster

Runar Jordahl
In reply to this post by Reinout Heeck
I did some informal testing and it seems like all versions of Windows
and most applications have the flicker problem I described. Dragging
windows or running an animation in PowerPoint gives the same results
as seen in my VisualWorks code example.

I did some of the same tests in OS X, and Apple seems to have solved
the problem, at least when dragging windows (I did not try
VisualWorks). I guess OS X have some kind of support for syncing the
raster. My guess is that VisualWorks does not use this feature on OS
X, and end up flickering also on this OS.

Microsoft is slowly catching up, and Vista directly supports smooth
screen updates:

"When using Windows Aero, open windows glide smoothly on your screen
when you move or resize them. There are no redraw artifacts, latency,
or "tearing" effects that you sometimes see, particularly in windows
that display dynamic content such as video."
http://www.microsoft.com/windowsvista/experiences/aero.mspx

Hopefully VisualWorks will one day also take advantage of this.

-Runar


On 3/30/06, Reinout Heeck <[hidden email]> wrote:

> Modern screens still get their data serially (line-byline, left-to-right), so
> the same problems still apply. Even if modern monitors buffer an entire frame
> (I have no idea whether they do this) the synchronization issues exist on the
> graphics-card end of affairs: if the card is busy sending lines to the
> monitor in an area that the pixmap is being copied to at that same time you
> get odd 'half pictures' being stacked on top of each other. If the copying of
> the pixmap is not synchronized to the monitor's frame rate that division line
> will move vertically (showing the interference between the monitor's refresh
> frequency and the frequency of pixmap copying). Since monitors have higher
> frame rates these days the problem my well be worse than in the old
> 'everything is 30Hz' days.
>
>
> Bottom line is still that VisualWorks does not directly support this kind of
> synchronization (...)