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 |
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 |
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 ------- |
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 > > |
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 |
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 |
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 |
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 >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 |
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 |
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 >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 |
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: ' |
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 (...) |
Free forum by Nabble | Edit this page |