Skip to content

screen.xml file format

The screen.xml file defines how the application's graphics are rendered. It consists of a single top-level MultiHead element which contains several child elements, including one or more window elements.

Tip

See client-screen-xml for the location of the file.

Info

Refer to video-wall-examples for full examples for specific configurations.

MultiHead parameters

Parameters that can be set for the top-level <MultiHead> element.

vsync

: Set to 1 to wait for the vertical synchronization when rendering a frame to eliminate screen tearing artifacts.

On Linux this basically caps the framerate to display refresh rate, which is typically 60. All displays should have the same refresh rate for this to work properly.

On Windows this is more complicated because of DWM. Setting this to 1 can cause double vsync to occur and the framerate to drop to 30. However, in single-window setups it is typically safe to enable.

In general vsync is almost always a desirable feature since it reduces tearing, but it will introduce some input lag which might make the application feel slow to respond.

Default: 1 on Linux, 0 on Windows.

Note

Enabling vsync only helps with tearing inside displays. If you want to reduce tearing between GPUs, you might need setup frame-locking or you could try to set gl-finish to 1.

layer-size

: Defines the size of the primary content, or root layer size, in the application in graphics coordinates. In practice, this means different things depending on the application:

**Canvus**: the default workspace size is the layer-size if you haven't defined any fixed workspaces.

Installations that have video outputs but don't have any fixed workspaces, layer-size should match the area reserved for workspaces. Otherwise the default workspace will fill the whole available area, overlapping with the video outputs.

**Launcher**: the background animation is rendered only in the root layer and by default the launcher menu is centered in the root layer.

Installations that have a main wall, breakout screens and video outputs, most likely should have the layer-size match the main wall size. This way the menu is centered in the main wall and the breakout screens and video outputs won't display any Launcher content.

**Showcase**: different structure layers (Overlay, Menu, Main, Background) have the same size as layer-size. In practice this affects things like relative sizes and locations for child items for these structure layers. For instance adding a picture with size "100% 100%" under the Background layer would have the same size as layer-size in screen.xml.

If set to default ("0 0"), the layer-size is calculated automatically from the graphics coordinates.

Default: "0 0"

gl-finish

: Enabling this may reduce rendering latency and tearing between GPUs by eliminating frame buffering but at a cost of reduced performance. On a low level this basically specifies if glFinish should be called after every rendered frame.

Default: 0

texture-upload-method

: Specify which method to use to transfer texture data to the GPU. All different options perform the same task, but use different OpenGL techniques. There can be a significant performance difference between the options, but it all depends on the platform and driver.

Options:

-   texture
-   buffer-upload
-   buffer-map (normally the fastest choice)
-   buffer-map-nosync
-   buffer-map-nosync-orphan
-   0 (same as texture)
-   1 (same as buffer-upload)
-   2 (same as buffer-map)

Default: 2 (buffer-map)

async-texture-upload

: If set to 1, some texture data will be uploaded asynchronously to the GPU using separate upload threads and OpenGL contexts. This can improve GPU upload throughput and reduce "Render collect" time and therefore improve performance.

This feature has caused stability issues with older Intel drivers.

Default: 1

prefetched-video-frame-count

: In video playback, the number of video frames to transfer to the GPU before they are needed. Setting this to 1 might improve application performance in certain cases, like when playing a huge video file.

Allowed values: 0 or 1.

Default: 0

Window parameters

Parameters that can be set for each element representing a window, e.g. <GPU1 type="window">.

location

: Window location in desktop coordinates. This doesn't affect which part of the application is rendered on this window, this just places the window on the desktop.

Origin (0, 0) is in the top-left corner of the primary display, so if you wish to place your window on a display left of the primary display, you need to use negative values (like "-1920 0").

On Windows, this is just the desktop location but in Linux this is relative to the X Screen origin, since all X Screens work as separate desktops with their own independent coordinate system.

Default: The window is placed on the center of the screen.

size

: Window size in desktop coordinates. Like location, this only affects the window size, it doesn't affect what is rendered inside the window.

Default: the size is 100% of the display in frameless mode or 80% of the display in windowed mode.

frameless

: Enable or disable frameless window mode.

Frameless window:

  • Doesn't have borders, title bar, system menu or minimize/maximize/close buttons
  • Can't be moved or resized
  • Can't toggle between windowed and full-screen mode using F11
  • Disables OS touch gestures on top of the window
  • Frameless mode is the recommended way of configuring video wall installations.

Also see stay-on-top and bypass-window-manager.

Default: true

stay-on-top

: Window is placed on top of other windows if stay-on-top is enabled. This is almost always what you want in frameless mode.

Default: true if frameless mode is enabled, otherwise false.

bypass-window-manager

: If true, the window will bypass the window manager on Linux. This makes the application visible on all virtual desktops and also makes the window stay on top of other "stay-on-top" windows.

This is needed to make sure we are always on top of system notifications, menus and other windows that have "stay-on-top" flag enabled as well.

Default: true if frameless mode is enabled, otherwise false.

fullscreen

: If true, the size attribute is ignored and the window is put to fullscreen mode, which might mean different things on different window managers and operating systems. Typically a fullscreen window fills just one screen in a multi-display environment.

Usually frameless mode is more reliable than fullscreen mode.

Default: false

resizable

: If true, the window can be resized. This flag should not be used with frameless windows. Resizable windows can also be toggled between fullscreen and windowed mode using F11.

Default: false

fsaa-samples

: Number of samples per pixel for full-screen multisample anti-aliasing. Setting this to 0 disables multisampling and improves rendering performance with a cost of aliased rendering. Set to 4 to improve picture quality.

With HiDPI screens multisampling can be disabled or the number of samples could be reduced to 2.

If the value is negative, a default value is chosen based on the available hardware. In practice this means that with Intel GPU we disable multisampling but with everything else we use value 4.

Default: -1

direct-rendering

: If enabled, the areas inside this window are rendered directly to the window. This gives the best performance. If disabled, rendering is done using off-screen buffers that adds overhead, but is required for frame lock and area color correction to work.

If you use frame lock, set this to false.

Default: true

screennumber

: X Screen number starting from 0. The location of the window is relative to the selected X Screen.

Only used in Linux.

Default: -1 which selects the current X Screen.

gpu-affinity-mask

: Controls GPU affinity for this window. GPU affinity in practice means which GPUs render this window. Almost always the default value should work, but in case of buggy drivers or just for debugging this can be useful.

The value itself is a bitmask, where bit 0 is the first GPU, bit 1 the second etc. When a bit is on, then that GPU is selected for this window.

Only used in Windows.

Default: The mask is calculated automatically based on the window size and position.

icon

: Path to the icon resource shown in the taskbar and window title bar for this window. Accepts a Cornerstone resource path (cornerstone:...) or an absolute file path.

Typically omitted in production video-wall deployments because frameless windows have no visible title bar. Set this only when running in windowed mode and a custom application icon is required.

Default: `"cornerstone:Icons/cornerstone-application-icon.ico"`

```xml
<GPU1 type="window">
    <icon>cornerstone:Icons/my-app-icon.ico</icon>
</GPU1>
```

Output parameters

A window can stream what it renders to the network as an NDI source by adding an <output> child element, e.g. <GPU1 type="window"><output type="ndi-output">...</output></GPU1>. An <output> sits beside <area> inside a <window> element; a window can have any number of outputs.

Info

The NDI runtime library ships inside the application's own folder and is loaded dynamically at run time. No separate NDI installation is required on the machine running the application.

type

: Selects the output implementation. Only ndi-output is available.

Unknown output types are ignored with a warning, and the window still loads normally.

Default: none — an `<output>` element must specify a type.

source-name

: The name of the NDI source as it appears on the network.

Default: `"<application name> <window element name>"`

framerate

: Maximum rate, in frames per second, at which frames are sent to the network. This never slows down rendering; frames are dropped at the output when the cap is reached.

Default: `0`, meaning every rendered frame is sent.

audio

: Set to 1 to include the application's audio mix in the NDI stream.

Default: `1`

groups

: Comma-separated list of NDI groups (p_groups) the source is advertised in. Leave empty to advertise in no group.

Default: empty

Info

Receivers see the source as MACHINENAME (source name) — the name of the machine running the application is always part of the identity, not just the source-name value.

Note

On Linux, avahi-daemon must be running for NDI discovery to work. Sending still works for a receiver that already knows the address, but the source will not be discoverable on the network without avahi.

The virtual window parameter

virtual

: Set to 1 to make this window render entirely off-screen, with no on-screen presence at all. Areas inside a virtual window still join the union of graphics bounds exactly like a physical display, so they participate in the wall layout normally — only the on-screen window is skipped.

When `virtual` is set to 1, the window parameters `location`, `frameless`, `fullscreen`,
`stay-on-top`, `bypass-window-manager`, `screennumber`, `resizable` and `icon` are ignored (a
warning names each one that was set), and `direct-rendering` is forced to 0.

Default: `0`

Recipes

Mirror an on-screen display. Add an <output> to an ordinary physical window. The NDI stream carries exactly what that display shows, alongside its normal on-screen rendering:

<window type="window">
    <frameless type="">1</frameless>
    <size type="">1920 1080</size>
    <area type="area">
        <graphicslocation type="">0 0</graphicslocation>
        <graphicssize type="">1920 1080</graphicssize>
        <location type="">0 0</location>
        <size type="">1920 1080</size>
    </area>
    <output type="ndi-output">
        <source-name type="">Mirror</source-name>
    </output>
</window>

Headless, stream-only host. Give a machine with no display a screen.xml whose windows are all virtual. Nothing is ever shown on screen; the application renders off-screen and streams:

<window2 type="window">
    <virtual type="">1</virtual>
    <size type="">1280 720</size>
    <area type="area">
        <graphicslocation type="">0 0</graphicslocation>
        <graphicssize type="">1920 1080</graphicssize>
        <location type="">0 0</location>
        <size type="">1280 720</size>
    </area>
    <output type="ndi-output">
        <source-name type="">Loopback Test</source-name>
        <framerate type="">30</framerate>
    </output>
</window2>

When a screen.xml has no physical window at all, nothing paces the render loop, so the application sleeps to the highest configured output framerate (default 60 if every output leaves framerate at 0).

Add an off-screen region beside an existing display. This is the case that most often surprises people, because adding the virtual window changes how the application lays itself out.

A virtual window's area joins the union of graphics bounds exactly like a physical display. If its area sits outside the region your existing displays cover, the total graphics area grows, and an application that derives its layout from that area will spread itself across the larger space — the on-screen display then shows only a portion of the interface, as though a second monitor had been plugged in.

That is correct behavior for a wall, but it is rarely what you want when you are only adding a stream. Pin layer-size to the region your physical displays cover, and the interactive area stays where it was while the virtual window renders beside it:

<multihead>
    <!-- Interactive area stays at the physical display's region. Content is
         still rendered outside these bounds - they bound interaction, not
         rendering. -->
    <layer-size type="">1920 1080</layer-size>

    <window type="window">
        <size type="">1920 1080</size>
        <area type="area">
            <graphicslocation type="">0 0</graphicslocation>
            <graphicssize type="">1920 1080</graphicssize>
            <location type="">0 0</location>
            <size type="">1920 1080</size>
        </area>
    </window>

    <!-- Renders the canvas region immediately to the right of the display,
         outside the interactive area, and streams it. -->
    <window2 type="window">
        <virtual type="">1</virtual>
        <size type="">1920 1080</size>
        <area type="area">
            <graphicslocation type="">1920 0</graphicslocation>
            <graphicssize type="">1920 1080</graphicssize>
            <location type="">0 0</location>
            <size type="">1920 1080</size>
        </area>
        <output type="ndi-output">
            <source-name type="">Projector</source-name>
            <framerate type="">30</framerate>
        </output>
    </window2>
</multihead>

Warning

Set layer-size before adding a virtual window whose area lies outside your existing displays. Without it the application rescales across the enlarged graphics area and the on-screen display appears to "zoom out" onto a fraction of the interface. See layer-size for what the setting means in each application.

v1 limitations

  • HX receive on Linux: the bundled NDI runtime dlopens FFmpeg 7 (libavcodec.so.61), while Ubuntu 24.04 ships FFmpeg 6. HX2/HX3 sources will not decode on stock Noble. Full-bandwidth NDI is unaffected. HX1 is unsupported everywhere.
  • Per-region output audio (only the widgets inside a virtual window's area, rather than the application's full mix) is not supported.
  • Rendering is not skipped when an output has no receivers connected — only the network send is skipped. Skipping the render pass itself is a future optimization.
  • The Showcase editor shows the raw ndi://... device string for NDI sources rather than a friendly name.
  • There is no runtime "add an output" UI; outputs are configured only through screen.xml.

Area parameters

Parameters that can be set for each element representing an area, e.g. <Area1 type="area">.

location

: Location of the bottom-left corner of the area relative to the bottom-left corner of the window in pixels inside the window. For legacy reasons the coordinate system has the vertical axis going up instead of down like all the other location attributes. Area with a location of (100, 100) would have its bottom left corner from 100 pixels from the left edge of the window and 100 pixels from the bottom edge of the window.

This doesn't affect which part of the application is rendered on this area, this just places the area on the window.

Almost always the default (0, 0) works fine, since the optimal setup is to have exactly one area per window, and it makes sense for that area to be the same size as the window.

Default: "0 0"

size

: Size of the area, in pixels, inside the window.

Default: size is the same as the window size.

graphicslocation

: See graphicssize below.

Default: "0 0"

graphicssize

: In the application virtual graphics coordinates, graphicslocation and graphicssize define the part of the application that is rendered to this area.

This doesn't affect where on the window the viewport is rendered, but it defines what part of the application is rendered here.

The graphics size doesn't need to be the same as area size or even have the same aspect ratio. The given part of the application is rendered so that it fills the whole area. Different areas can render arbitrary parts of the application, even if the parts overlap. For instance, one could have a big three window 9x3 wall running Showcase, and then one extra area in the first window with area size 900x170 and graphics size 17360x3260 to get a "preview viewport" of the whole application on top of the application.

However, in a typical use case the graphics size does match the area size so that we have 1:1 pixel mapping from the virtual application graphics coordinates to the window coordinates so that all the UI elements have the correct size.

Default: size is the same as the area size.

seams

: Edge-blending widths in pixels for projector overlap regions. The value is a four-component vector: left right top bottom.

When seams are set, the graphics bounds of the area are extended outward by the specified amounts so that the overlapping region is rendered by two adjacent areas simultaneously. The rendering pipeline blends the brightness of the overlapping pixels to avoid a bright seam between projectors.

Use this when two projectors physically overlap and you need to fade out each projector's contribution across the shared region.

Default: `"0 0 0 0"` (no edge blending)

Example — 40-pixel left and right overlap for a projector blend zone:

```xml
<Area1 type="area">
    <graphicslocation>0 0</graphicslocation>
    <graphicssize>1920 1080</graphicssize>
    <seams>40 40 0 0</seams>
</Area1>
```

keystone

: Projector keystone (perspective) correction. The value is a child element containing four corner vertices and an optional rotation count.

Each vertex (`v1`–`v4`) is a normalized 2D float coordinate in the range `[0, 1]` describing where the corresponding corner of the projected image should map to. The default (identity) positions are:

- `v1` — top-left `0 0`
- `v2` — top-right `1 0`
- `v3` — bottom-right `1 1`
- `v4` — bottom-left `0 1`

Adjust vertices to correct for physical projector misalignment. `rotations` records how many times the vertex ring has been rotated (used by calibration tools; leave at 0 unless you know what you are doing).

Use this when a projector cannot be perfectly aligned mechanically and you need to skew the rendered image to match the physical screen surface.

Example — slight keystone correction pulling the top-right corner inward:

```xml
<Area1 type="area">
    <keystone type="">
        <v1>0 0</v1>
        <v2>0.97 0.02</v2>
        <v3>1 1</v3>
        <v4>0 1</v4>
        <rotations>0</rotations>
    </keystone>
</Area1>
```

method

: Selects how the area is composited to the framebuffer when keystone correction is active.

- `0` — `TEXTURE_READBACK`: renders the scene to the framebuffer first, reads the result back into a texture, then re-renders that texture with the keystone matrix applied. More GPU bandwidth but correct with `direct-rendering` disabled.
- `1` — `MATRIX_TRICK`: applies the keystone transformation directly as an OpenGL projection matrix during rendering. Lower overhead and the recommended default.

Default: `1` (MATRIX_TRICK)

```xml
<Area1 type="area">
    <method>1</method>
</Area1>
```

colorcorrection

: Per-area 2D color correction curves for the red, green, and blue channels. Stored as a child element containing curve control points, plus gamma, brightness, and contrast sub-elements.

This is hardware-path color correction used on MT cells. For most deployments the default identity curves are correct and this element should be omitted. Use the calibration tooling to generate this data rather than editing it by hand.

Default: identity (no color correction applied)

```xml
<Area1 type="area">
    <colorcorrection type="">
        <brightness>0 0 0</brightness>
        <contrast>1 1 1</contrast>
        <gamma>1 1 1</gamma>
    </colorcorrection>
</Area1>
```

rgbcube

: Per-area 3D color lookup table (LUT) for software color correction. Provides full RGB-to-RGB remapping via a grid of sample points across the color cube.

When an `rgbcube` is defined for an area, Cornerstone uses it for color correction instead of the 2D `colorcorrection` curves. This element is generated by the color calibration tooling and should not be edited by hand.

The sub-elements `division` (grid density) and `rgb-table` (packed sample data) are written by the calibration workflow.

Default: undefined (no 3D LUT applied)

```xml
<Area1 type="area">
    <rgbcube type="">
        <division>3</division>
        <!-- rgb-table data generated by calibration tooling -->
    </rgbcube>
</Area1>
```