PVR is currently implemented around the Tcl/Tk interpreter developed by John Ousterhout [Ous93]. The main architecture features are illustrated in Figure 7. The Tcl/Tk interpreter is used as the system glue; it connects all major parts of the system in the client side and provides the sessions handlers with file I/O connectivity and TCP/IP connections. It also provides mechanisms where windows can be opened for user interaction and image display. The current version has over 12,000 lines of C code. Using Tcl/Tk has greatly simplified the code.
Figure 7: PVR Architecture. The Tcl/Tk core acts as
glue for all the client components. Everything with the exception of
the renderers run on the user's workstation. The renderers
run remotely on the parallel machines.
The client program is implemented as a single process (this design decision was made to make ports for other operating systems easier). We have augmented the Tcl/Tk interpreter with TCP/IP connection capabilities and session handling commands. The implementation of the session handling is as follows. Each session has its own private data structures and its own TCP/IP connection to different renderers. In order to make it possible to use several sessions in a single Tcl/Tk interpreter, we use the Tk_CreateFileHandler() routine to arbitrate between input from the different sessions (a UNIX select call and polling could be used instead, but would make the code harder to understand and overall complex). Sessions work as interrupt driven commands, responding to requests one at a time. Data structure locking and disabling interrupt are needed to ensure consistency inside critical sessions. The connection code with the server process (in the parallel machine) is implemented in two stages as described next.
The server is implemented as a daemon running in the parallel machine. It just waits on a well-known port for connection requests. Once a request is made it forks a handling process that will be responsible for allocating processors and communicating with the session on the client. In the Intel Paragon, the handling process allocates the computing nodes, and runs the renderer code on them. The connection process is illustrated in Figure 8. One server can allocate several renderers, once the server is killed, it kills all its children before exiting.
Figure 8: Each session can open up one renderer. It does
this by sending a message to the server in the parallel machine.
The renderer code is divided into three pieces (illustrated in Figure 9):
Figure 9: The host receives high level commands like
rotations, then translates them into simple transformation matrices
commands and broadcasts to every cluster. The collector receives and
groups images back together and sends an ordered image sequence to the
client application.
Full implementation details of all the PVR components are given in [LS95].