Sunday, January 9, 2011

XBMC and NVidia's TwinView

I was looking for a decent media center - mostly to watch movies with an overhead projector connected to a PC. The PC is running Linux and I would like to be able to select a movie, change the volume, pause etc with my Medion (read: cheap, RF, USB connected) remote. One day I stumbled upon XBMC. It turned out to be a decent piece of software. Configuring the remote was easy. But...

I must mention here that my display setup uses the NVidia's TwinView, which serves me well. My main LCD monitor is connected through a D-Sub while the beamer via HDMI. They form a dual-screen setup with the beamer on the right of the LCD.

But there is always a catch... Actually two of them.
  1. XBMC's fullscreen ignores TwinView, so it spans both displays, or the other display is turned off. 
  2. There is video tearing visible while XBMC is running on the beamber, there is no tearing if it runs on the LCD.
The first issue can be fixed by making XBMC use so-called windowed mode. It appears as a window then. Having a window and using wmctrl it is possible to make it look like fullscreen.
The second issue regard configuring the NVdia in a proper way which makes OpenGL sync to the specified display instead of the first one. It can be achieved by exporting two environment variables __GL_SYNC_TO_VBLANK=1 and __GL_SYNC_DISPLAY=name_of_the_display_to_sync_to.

So here comes my magical bash script which launches the XBMC with a proper syncing enabled and shifts it to the beamer making the window fullscreen (mind that the beamer is on the right of the LCD, and the LCD is 1280x1024).

Enjoy.
#!/bin/bash

move_and_fullscreen(){
  NAME='XBMC Media Center'

  while [ -z "`wmctrl -l | grep \"$NAME\"`" ]
  do
      sleep 1
  done

  wmctrl -r "$NAME" -e '0,1280,-1,-1,-1'
  wmctrl -r "$NAME" -b toggle,fullscreen
}

move_and_fullscreen &
__GL_SYNC_TO_VBLANK=1 __GL_SYNC_DISPLAY_DEVICE=DFP-0 SDL_VIDEO_ALLOW_SCREENSAVER=0 exec xbmc

Update: As of XBMC 10.1 I had to add SDL_VIDEO_ALLOW_SCREENSAVER=0 to disable screensaver while running XBMC. The above approach uses the windowed mode of XBMC which enables system screensaver now - it kicks in while watching movies :( (the screensaver is disabled in the fullscreen mode only).

18 comments:

  1. Tks! I was having the same issue as you with the screensaver/monitor going to sleep.

    This worked just fine!

    best regards

    ReplyDelete
  2. #!/bin/bash
    disper -d auto -e -t left
    sleep 1
    __GL_SYNC_DISPLAY_DEVICE=DFP-1 gnome-shell --replace --display=:0 &
    move_and_fullscreen(){

    NAME='XBMC Media Center'

    while [ -z "`wmctrl -l | grep \"$NAME\"`" ]
    do
    sleep 1
    done

    wmctrl -r "$NAME" -b toggle,fullscreen
    }

    move_and_fullscreen &
    __GL_SYNC_TO_VBLANK=1 __GL_SYNC_DISPLAY_DEVICE=DFP-1 SDL_VIDEO_ALLOW_SCREENSAVER=0 exec xbmc

    ReplyDelete
  3. Awesome, script works perfectly. Thanks!

    ReplyDelete
  4. Thanks for sharing. Works for me... kind of. XMBC starts on the monitor where is my cursor. And I still have tearing. Ideas ?

    ReplyDelete
    Replies
    1. Regarding wrong monitor: take a look at the first wmctrl line - there is the 1st monitor resolution given: 0,1280 - replace it with yours, assuming that the 2nd monitor is on your right.

      If you still see tearing check the display device name. Open nvidia-settings and you should see (under GPU subtree) all available display devices. In my case these are: CRT-0 (1st monitor) and DFP-0 (2nd monitor). Just put the name you have in the very last line of the script instead of DFP-0.

      I hope it'll help.

      Delete
    2. Thanks for answering. My primary monitor is an lcd 1280x1024 d-sub connected, my second is a full hd led tv (DFP-1) hdmi connected. The tv is on the right of my primary monitor. XBMC is set on windowed mode. Nvidia 440GT, 304.64 driver. I modified the tv name (DFP-1). Still no luck. It drives me nuts.

      Delete
    3. Emil, It should work, I'm not sure why it doesn't... sorry.

      Delete
    4. I've done some more testing. I solved the tearing by adding __GL_SYNC_DISPLAY_DEVICE="DFP-1" to /etc/environment so now vsync is enabled permanently on the second monitor. As for the wrong monitor, if I remove the last wmctrl line, xbmc starts always on the second monitor. But with the last line, it appears for a fraction of a second on the second monitor and then gets maximized on the primary. Thoughts ?

      Delete
    5. The first wmctrl:

      wmctrl -r "$NAME" -e '0,1280,-1,-1,-1'

      moves the window to the monitor to the left of the primary one, assuming that the primary is 1280 in width.

      Then the second wmctrl comes:

      wmctrl -r "$NAME" -b toggle,fullscreen

      and it just tells the window manager to toggle fullscreen property on the window, which suppose to make the windowed xbmc go full screen. If it doesn't it can be caused by the windowed mode not turned on, or a bug/feature in the Window Manager e.g. going full screen on the primary display, or the display the mouse pointer is at, instead of the one with the actual window.

      Delete
    6. Thanks for taking the time to reply. I finnaly managed to solve it following instructions from here. http://forum.xbmc.org/showthread.php?tid=139854 I hope it will help others too if you method doesn't work. Anyway, I've switched to elementary OS and I can set separate x screens. Goodbye twinview hacks !

      Delete
    7. I have pretty much exactly the same setup as Emil, and was having the same problem with XBMC being made fullscreen on the wrong (leftmost) screen. I found that it was because it was being opened as a maximised window on the left screen, and so the wmctrl move command "-e '0,1280,-1,-1,-1'" was being ignored.

      I fixed it by adding the line

      wmctrl -r "$NAME" -b remove,maximized_vert

      before the move command, and it seems to be working just fine now.

      Delete
    8. Same problem here (gnome-shell 3.8). Only works when switching the move and the toggle fullscreen command.

      Delete
  5. It works great! Very handy.

    ReplyDelete
  6. awesome, works on ubuntu-gnome (w/gnome-shell 3.8) on 13.10

    ReplyDelete