Quick Tip: Fixing V-Sync ("Tearing") Issues in Flash

In today's (Very) Quick Tip, you'll learn how to solve the common problem of flickering or tearing. This is a horrible effect in Flash where bitmaps flicker as they are updated, or appear to tear into two images (as in the thumbnail).

What Causes These Issues?

In a nutshell: tearing occurs when Flash draws information from two different frames to the screen at once. In the thumbnail image above, you can see how this might look when panning across an image of a tower; the bottom part of the image is from one frame, while the top half is from the next. When watching this in motion, you would only see it for a fraction of a second at a time, but it would still be noticeable.

This is commonly solved using "V-sync" (vertical synchronization), which stops the video card drawing anything to the screen until the screen's next refresh cycle. However, Flash has really poor support for V-sync, because the frame rate of Flash Player is different to the desktop's vertical refresh rate, meaning that objects that have a lot of height will be hit hard by tearing. This is true even if Flash's frame rate is equal to the desktop vertical refresh rate, as they are still not synchronized.

Now you may be wondering: Why don't Adobe fix this problem? The reason is that Flash uses a timeline, and changing the frame rate consequently changes the speed of playback. If you made a game or image gallery running at 60 frames per second and the desktop vertical refresh rate was more than 60 frames per second, you would either have slight stuttering (if you left the movie at 60fps), or would have to play the movie back faster to sync with the desktop. For most content, this wouldn't be recommended at all!

This is a problem game developers have wanted Adobe to fix for a long time but it's obvious that there are issues with them doing so. So, at the moment, we developers have to come up with creative ways to solve this problem ourselves. There is no easy way to fix it on all computers, but as most monitors have a refresh rate of 59.9 or 60 then you can set the frame rate to 60 to solve it for most users. However, this requires more processing power and could slow your application down.

The best way to solve this at the moment is fairly simple and easy to do. It doesn't fix the underlying cause, but it does help reduce the amount of tearing as much as possible.

How Can I Reduce Tearing?

Hardware Acceleration Level 1: Direct is the key to helping the tearing problem. This can be set by opening the HTML file where your SWF is embedded and editing the parameters for the Flash object.

The flag you want to set is wmode: "direct". This line goes in the 'params' section of your HTML code. That's it, that should help dramatically reduce the tearing. If you want to know why, look at Adobe's page on hardware acceleration. It explains a little about both levels of hardware acceleration. For even more information, check out this in-depth article.

Anything Else?

Yes; another thing to mention is that, the more objects you have on the screen, the more obvious the tearing will become. Smaller items are not usually affected by V-sync issues, but items on the screen which are large make it very obvious, so keeping the number of large objects to a minimum is a good idea.

Also, using bitmapData.lock() and bitmapData.unlock() is recommended and has helped some people with this problem. Locking a BitmapData object stops any bitmaps from being redrawn until it is unlocked, which is a good idea if you need to make multiple changes between frames. To learn more, take a look at this blog post.

Conclusion

You can do a few things to help reduce tearing but you cannot eliminate it completely. Reducing the amount of large objects, setting wmode:"direct" and using bitmap locking are the best ways to help reduce tearing.