# Using Chromium with DMX

DMX allows X to be run on a cluster of systems such that the X display/desktop can span many individual screens. For example, a cluster of 12 computers running X can be harnessed to provide a large tiled display of 4 x 3 screens. Windows can span screen boundaries.

Needless to say, DMX works with X-based systems; not Windows.

Since version 1.2, Chromium has support for DMX so that OpenGL applications can work transparently on a DMX display.

Previously, when Chromium's tilesort SPU was used to drive a large, tiled display there were a number of problems:

- The original application window was created but left empty while Chromium rendered to the back-end screens.
- Mouse-based interaction was difficult because the pointer wasn't visible with the Chromium rendering.
- Only one OpenGL window was supported.

These problems are now fixed for DMX displays since Chromium directly renders into the real X windows. In short, OpenGL applications "just work" the way you'd expect.

## Setup

You should already have DMX up and running on your graphics cluster. See the DMX documentation for instructions.

Furthermore, you'll need to copy the dmxext.h header file from dmx/xc/include/extensions/dmxext.h into your usual X header file directory, such as /usr/X11R6/include/X11/extensions. Then, the DMX client library, libdmx.a should be copied from dmx/build/xc/exports/lib/libdmx.a to your usual X library directory, such as /usr/X11R6/lib/.

You'll need to compile Chromium with DMX support. To do this, edit cr/options.mk and set `USE_DMX=1`.

Then, rebuild Chromium by doing make clean followed by make.

If compilation fails, be sure the dmxext.h header is in the right place (see above).

## Running Manually

Edit the sample mothership/config/dmx.conf configuration script - you'll have to edit the TILE_ROWS, TILE_COLS and HOSTS settings, at least.

Start the mothership: python dmx.conf appname

On each of the back-end systems:

- open a shell.
- set the DISPLAY env var to the native X display (i.e. "cluster7:0")
- set the CRMOTHERSHIP env var to the host where the mothership is running.
- set the LD_LIBRARY_PATH env var to your Chromium lib directory
- start a crserver

On the DMX front-end system:

- open a shell
- set the DISPLAY env var to the DMX server (i.e. "frontend:1")
- set the CRMOTHERSHIP env var to the host where the mothership is running.
- set the LD_LIBRARY_PATH env var to your Chromium lib directory
- start a crappfaker

At this point, your OpenGL application should be running on DMX.

If everything's working correctly you should see "GL_CR_dmx" in the list of OpenGL extensions listed by the glxinfo program.

## Running with Auto-start

Ideally, one would like to able to start an OpenGL application in the normal manner and have it use DMX+Chromium automatically, without manually starting a mothership and set of crservers as we did above. The auto-start feature lets you do just that.

### Prerequisites

1. Your ~/.crconfigs file needs to be setup. Specifically, it needs a line like this:

   * /usr/local/Chromium/cr/mothership/configs/autodmx.conf %m %p

   This tells Chromium's libcrfaker to use the autodmx.conf config file when running any application (indicated by *). The %m is replaced by a random mothership port. The %p is replaced by the program name.

2. libGL.so and libGL.so.1 must be symlink to libcrfaker.so

3. The back-end/cluster machines must have the crserver binary in the search path (typically /usr/local/bin or /usr/bin) and a properly set LD_LIBRARY_PATH (you can tweak it below).

4. rsh to the back-end/cluster machines must work.

5. You may need to tweak the value of 'crdir' in the autodmx.conf file.

### How it works

1. When the app starts, libcrfaker will fail to find the mothership on its first try. That'll signal it to search the .crconfigs file for a mothership config to spawn. libcrfaker will choose a random port number for the mothership.

2. The mothership is spawned with autodmx.conf. In turn, it uses rsh to start up the crservers on the back-end machines. Another random port number is used for the crservers.

3. Control returns to libcrfaker where it proceeds to load the client-side SPU chain (tilesort). Then, control returns to the application.

### Troubleshooting autodmx.conf Problems

First, verify that libGL.so and libGL.so.1 resolve to libcrfaker.so by running ldd on your application. Make sure your DISPLAY environment variable is set to the DMX display.

To make sure the back-end servers are properly configured:

- Make sure the options in dmx.conf are set correctly then start the mothership with that configuration:

  python dmx.conf

  You should see something like this:

  This is Chromium, Version 1.5
  Start a crserver on cr1
  Start a crserver on cr2
  Start a crappfaker on foobar

- Manually start each of the crservers using rsh, for example:

  rsh cr1 crserver

  If rsh complians about authorization or prompts for a password, edit the .rhosts file on the servers.

  If you see "crserver: Command not found." it means that the crserver program is not in your search path. Edit the servers' .cshrc or .bashrc files and add /usr/local/cr/bin/Linux (or thereabouts) to your path variable.

  If you see "Couldn't connect to the mothership" it means the CRMOTHERSHIP environment variable isn't getting set. Set it in the servers' .cshrc or .bashrc files to 'foobar'.

  If you get "crserver: error while loading shared libraries: libspuload.so: cannot open shared object file: No such file or directory" it means your LD_LIBRARY_PATH environment variable isn't set correctly. Again, edit the servers' .cshrc or .bashrc files.

  Otherwise, the crserver should be running at that point. Start the remaining crservers.

- Now you should be able to start the application and see it running on the DMX display.

Now, exit your application and return to autodmx.conf. Simply running an OpenGL app should cause it to run on DMX. If not, read this section again or ask for help on the Chromium mailing lists.

### NVIDIA Performance Tip

If you're using NVIDIA's OpenGL drivers and are experiencing poor performance on the DMX display it may be because you're using too much VRAM and falling back to software rendering. This inadvertantly happens because the render SPU may be creating GLX windows that are never used. A simple solution to this problem is to set the render SPU's default window size very small, say 2x2 pixels. See the dmx.conf file for details.

## Configuration File Details

The dmx.conf and autodmx.conf files are example configurations for using Chromium with DMX. If you decide to change them or make your own configuration file there are a few critical settings to be aware of.

The client/application node must be configured to track window size and position changes:

clientnode.Conf('track_window_size', 1)
clientnode.Conf('track_window_position', 1)

The tilesort SPU must be set to use DMX:

tilesortspu.Conf('use_dmx', 1)

The best bucketing mode to use is 'Non-Uniform Grid'. The 'Uniform Grid' mode can't be used since it's extremely rare for a window to be subdivided into identical tiles.

tilesortspu.Conf('bucket_mode', 'Non-Uniform Grid')

The server/network node must be configured to use DMX. Optimized bucketing is of no use and should be disabled.

servernode.Conf('use_dmx', 1)
servernode.Conf('optimize_bucket', 0)

The server's render SPUs should be configured to render into the application window and the SPUs needs to know the appropriate X display for the back-end X servers:

renderspu.Conf('render_to_app_window', 1)
renderspu.Conf('display_string', HOSTS[n] + ":0")

## How Chromium Works with DMX

Each of the back-end systems runs a crserver. Each crserver has a render SPU.

The mothership is configured for a crNetworkNode (crserver) on each back-end server. A tilesort SPU is configured for the front-end application (crappfaker).

Chromium's libGL faker loads the tilesort SPU. When a new OpenGL window is created, the tilesort SPU uses the DMX extension to find the window information on the back-end X servers which corresponds to the new X window. The tilesort SPU directs the N back-end render SPUs to directly draw into the back-end windows.

Whenever the DMX OpenGL window is moved or resized the tilesort SPU recomputes a new tiling and sends that information to the backend crservers.