How to fix video tearing on Chrome/Chromium and Compiz

One thing I really like about Netflix is their excellent device and browser support. Unlike a certain other streaming service (the one from the company also selling books and clouds), which wouldn't allow watching their streams using an Android tablet (bizarrely, smartphones were somehow allowed...?) and requires Flash and/or Silverlight in the browser, Netflix only requires a browser that supports the HTML5 Media Source Extensions (plain "old" HTML5 video tag support is not enough), the HTML5 DRM extensions a.k.a. EME and one of the three supported DRM plugins (Microsoft's Playready, Apple's Fairplay, or Google's Widevine; used by and shipping with Windows/IE, Safari on OS X and Chrome, respectively). Of course, the DRM requirement is annoying (somehow, these things tend to be broken sooner rather than later and only make things inconvenient for legitimate customers), but it is much better than those horribly outdated and inefficient browser plugins.

The only thing that was annoying me was a very annoying case of screen tearing using Chrome in fullscreen on my laptop running Unity/Ubuntu. This was never an issue for me with other browsers (e.g. Firefox), video players or games, so I initially suspected a bug in Chromium and filed a bug report. Thanks to some very helpful comments on that bug's discussion thread, I have been able to finally understand what is going on.

However, as it turns out, the problem seems to be actually caused by Compiz (the default window manager of Unity on Ubuntu), or more specifically, its "unredirect output" feature for fullscreen applications. Compiz is a compositing window manager, which means that applications do not draw directly to the framebuffer, but to a texture in video memory; the window manager then uses the GPU to display all windows on their respective positions. This is both more efficient (for example, dragging a window doesn't require all affected applications to redraw their content up to 60 times per second anymore) and visually pleasing (it prevents those ugly broken windows that appear when dragging a window over another window whose application is not responding to redraw calls anymore).

Of course, while compositing all those windows/textures on the GPU is very efficient, it is still not free; especially when only a single full-screen application like a video player is being displayed, compositing is only a waste of resources. "Unredirect output" seems to allow such full-screen applications to again draw directly to the framebuffer (as opposed to a texture). However, some applications seem to have problems doing just that; they somehow get their timing wrong and draw their window contents at the wrong moments (i.e. not during the "vertical sync period" a.k.a. VSync), which leads to visual tearing.

It turns out that Compiz (at least on my distribution, Ubuntu 14.10) already comes with a pre-populated list of applications that are excluded from unredirecting. That list explains why I was experiencing tearing in Chrome, but not in any other application: All video players and other applications I have tried are preloaded on that list – except Chrome or Chromium!

(any) & !(class=Totem) & !(class=MPlayer) & !(class=Vlc) & !(class=Plugin-container) & !(class=Firefox)

Adding filter clauses for both Chrome and Chromium completely fixes the issue for me (the list can be accessed and modified in the "Composite" tab of the "CompizConfig Settings Manager", which should be available in your distribution if it ships with Compiz):

[...] & !(class=^Google-chrome) & !(class=Chromium)

This fix should solve the problem regardless of your graphics card manufacturer; if you are using an Intel GPU, you might also have luck with enabling the TearFree option of the video driver, which might or might not be more efficient and/or cause other problems with your graphics – I have decided to use the Compiz fix, since it aligns with the way all other applications already are drawing their fullscreen windows on my system.

If you are experiencing the same problem, let me know if this fix helps in the comments!

Comments !