Tony Polinelli
Tarwin Stroh-Spijer

contact [at]
touchmypixel.com

6/25 Easey Street
Collingwood, 3066
Vic, Australia

+61 3 8060 5321

Getting smooth verticle scrolling with flash

We are working on a top down racing game, where the background scrolls vertically. This soulds like something flash should be able to do – no sweat! I’ve run into two issues:

1 – massive screen tearing – as the whole screen is scrolling vertically

2 – fluctuations in the processing time of frames, causes non-smooth motion (i think)

Here is a simple test of black balls falling down the screen. You should see tearing on the circles, rending issues (the bottom of the circle is cropped off sometimes) and jumpy verticle motion. I’ve tested on various computers+systems & it seems the issues running from worst to best are as follows:

VIEW TEST – maximise the window for most shocking results

WORST
mac osx
windows 7
windows xp x64
windows vista
windows xp
BEST

To me it doesnt make much difference between firefox, ie, chrome. Most tests were run on QuadCore 2.5ghz comps. Except windows XP, which is P4 3.0, and macbook 2.4. – funnily the slowest comp (p4) ran the best.

It is quite common knowlege that flash doesnt perform any doublebuffering or v-sync, to fix screen tearing. UnitZeroOne has a great article on this. Luckily flashPlayer 10 has a new WMODE – DIRECT, which seems to fix the issue a fair bit.  According to adobe it: “The direct WMODE will use your video card to paint pixels to the screen as fast as possible while freeing up your CPU to work on other tasks”

This seems to have a few issues with rendering (for us thus far) But it is a LOT smoother. It seems that it shouldnt have too much of a speed decrease (like transparent/opaque) either, after looking at some tests

Circle test in:

Window

Transparent

Opaque

Direct

GPU

The final issue:

AS you can see, the motion is still not totally smooth in DIRECT mode. It seems that flash has issues with updating the frames at a constant interval, which is noticable when i want a constant scroll. I dont know if there will ever be any way to get around this.

any ideas?

download test source

Cheers! Tony

UPDATE:

I’ve made a new version which moves the balls based on time, rather than frames. It basically moves 300pixels/second. ~ the same speed as before. It doesnt seem to make too much differnce – sometimes you get large jumps as the time lapses, and then the balls need to catch up – so not a great fix, but interesting.

Window – Time based

Direct – Time based

download v2 test source (only haxe version is time based)

23 comments

  1. bog.imp

    What about bitmap ?


  2. Good point –
    In the game i am working on everything is bitmapCached, the background is a series of tiles, i have tried the scrollRect to make it smoother too – this all speeds things up, but it will not reduce the flicker that you get with wmode=window, etc.

    I should have enabled cacheAsBitmap in the test here too- i just wanted this test to be VERY basic, to see if it was flash’s rendering that was causing gitter, or the more complex things (box2d etc) going on in my game. If you think about scrolling vertically is a terrible thing to do if you dont have vsync.


  3. Are you doing your positioning based on time or elapsed frames?


  4. ooh – excellent point. I am just adding a constant value – i really should multiply by dt – cant believe i didnt think of that! will try


  5. Tony, don’t forget to let us know how it worked for you.


  6. When you check the redraw regions, there is a lot of white space that is being redrawn. If you could minimise this, then it would fly a lot faster. Essentially it’s redrawing the screen too much. The smaller these areas the fast it will be.

    http://tinypic.com/r/2820w7a/6


  7. I’ve also done some tests using smooth time based animation. Just drag the circle around:
    When using wmode=window, the circle always seems to be cut off at one edge, depending on the drag speed: http://www.polygonal.de/dev/tearing/index_wmode_window.html
    With wmode=direct, the circle is drawn correctly, but there is a visible lag in the rendering:
    http://www.polygonal.de/dev/tearing/index_wmode_direct.html
    From my tests it doesn’t matter if I’m using vectors, bitmaps or cached bitmaps.


  8. Simon>
    This is just a simple test – in the final game the whole background is scrolling unfortunately, so redraw cant be avoided. I dont know if it would be possible to avoid this anyhow.

    michael>
    hmm – it doesnt seem too laggy on my system (i get terrible tearing + lag on window too tho), but i hear what your saying.

    Its a pity that it seems its just bad rendering in general – its wasted a whole day getting this kinda working, as scrolling my background just looks SOOO terrible. I’ve found some wierd bug arise with bitmap caching a lot of items in direct mode, some just dont render correctly (as a flat color)- so i’ve had to limit the length of my track (i guess i should manually add/remove items, not just lay them out in a large track layout). – issues that you dont get in ‘window’ mode however- very annoying.
    I dont think there is much more can be done direct mode is a good step up on pc (not much affect on the mac) – so a step in the right direction.


  9. I just tested all examples inside a virtual machine (VirtualBox) running WindowsXP and there is no tearing at all, regardless of the current wmode. So I guess it’s an issue with the graphics drivers. I hope Adobe will investigate and fix this issue.


  10. tony did’t you have the same problems when you worked on scary girl?
    are using pretty big images as background there.

  11. Scmorr

    Ha! I'm someone found this issue too.
    I've found only one workaround for this and use it in my game in development.

    1. Setup 100fps in publish settings (or in [SWF(... frameRate = "30")] ). You can setup 33fps - value doesnt matter, it should be only more then needed fps.

    2. Use limiter code in main cycle, something like this:

    CODE:
    1. protected var currentTime : int;
    2.  
    3.         public function onEnterFrame(e : Event) : void {
    4.  
    5.             var newCurrentTime : int = getTimer();
    6.  
    7.             var dtInt : int = newCurrentTime - currentTime;
    8.            
    9.             while (dtInt <37) {
    10.                 dtInt = newCurrentTime - currentTime;
    11.                 newCurrentTime = getTimer();
    12.             }
    13.             var dt : Number = (newCurrentTime - currentTime) * 0.001;
    14.            
    15.             currentTime = newCurrentTime;
    16.             }

    37ms for frame in this example means 27fps. Really stable, smooth 27fps. And without "massive screen tearing".

    There is only drawback here - it will eat all CPU perfomance, even on light scenes.

  12. Scmorr

    Sorry for misprints:

    - [SWF(... frameRate = "100")]
    - while (dtInt < 37) {


  13. In Scarygirl I think the problem was mitigated by the fact there was never much fast vertical movement. We just had a bunch of Bitmaps sitting in a MovieClip we moved around, so it's pretty similar to a bitmapCached vector that's not moving in these tests.

    The really wacky thing was, as Tony said, that there was strange rendering bugs. We had about 53 600x625 tiles, one above another, that was moving pretty fast (it's a racing game). For some reason the ones on the bottom of the rendering stack where just showing as a flat colour, at least for part of the sizes. The rest were then fine.

    The really wacky thing was that if we had the blocks that screwed up at the end of the track we'd get an almost "hall of mirrors" effect when the track ended.

    We found if we removed two of them it'd be fine though. Insane!


  14. So yes - you can see tearing in scarygirl - for instance, if you go to the swimming level (second one) and swim up/down you can see noticable tearing. It isnt as much of a problem there however, as the motion is quite slow.

  15. Scmorr

    I'm sorry, I've experiment with you code and... your case isnt my case. I suppose this is internal rendering issue of flash player, because I've test your code with copyPixels to background bitmapData and even bitmapData.scroll method, which should give us a guaranty of synchronous circles moving. But I've seen tearing anyway.

    Are you testing this on dual CPU computer? Mine is dual, I will try it on single CPU comp.

  16. Scmorr

    Tearing on Intel Dual Core, single AMD, ATI video, Nvidea video, so...


  17. We have Q6600 quad core, ATI4800 -
    so you are saying that things still tear - that is what i am saying too. It should be a bit better in wmode=direct - but still jumps (not tears) every now and then.

  18. Scmorr

    If you submit this issue into Adobe JIRA - give us a link here - we will vote for it.


  19. I'm sure Adobe would be quite aware of it, there are a few existing tearing bug posts on there - mostly focused on tearing video. One on multicores- saying that it doesnt happen as much with a singlecore (fix = use older player which only supports a single core - interesting)
    http://bugs.adobe.com/jira/browse/FP-2054
    i have voted - but by the assignee's status of priority=none - i dont think Adobe will give it much attention. They seem to be adding better hardware support etc. lately, so lets hope they work on double buffering in the future.

  20. Scmorr

    We dont know is this bug similar or not, cos I have even greater tearing and jumps on single core computer (just tested). And - let Adobe check this issue and let Adobe will decide - is it double-buffering problem or smthing other. Your issue example is more fundamental, so it would be great to have this bug in database. I try to popularize it and bring as many votes as I can.


  21. Tearihg on Intel Dual Core, sinfle AMD, ATI video, Nvid3a video, so...;

  22. Kubson

    In Safari on MacOS it works much better that in Chrome on my computer.

 

Leave a Reply

Our Friends:

Powered by haXe / poko cms | Copyright 2008-09 TouchMyPixel