Porting software from one system type to another is an art which requires an in-depth understanding of the abilities and idiosyncrasies of both the source and target platform. This section is intended for experienced programmers and experienced users of IRIS Performer. This section describes the issues you are likely to encounter when bringing your existing IRIX code base to Linux.
IRIS Performer 2.3 for Linux is fully API-compatible with existing IRIS Performer 2.2 applications built for IRIX. We have made an effort to make porting as easy as possible by leaving the API mostly unchanged and adding prominent warning messages to your program output if unsupported functionality is utilized. It is trivial to port most simple programs and even more intricate applications like perfly can be ported to Linux with only a small amount of effort. However, your application may be considerably more complex or rely on functionality that is not available in Linux or that is not supported in this release. For most applications, this will not be the case.
The following sections categorize the porting issues in the following manner:
header files
endianness
compiler differences
features and functionality not supported in this release
guidelines for new applications
Some of the IRIX-based C or C++ header files your program uses through #include's may not be available on Linux platforms, or the structures they define may be contained in a different header file than on IRIX. Such issues can usually be resolved by visual inspection of the header files themselves.
Using the C language version of the IRIS Performer example application perfly as an example, the following code was changed to remove headers:
#ifndef __linux__ #include <sys/sysmp.h> #include <bstring.h> #else #include <limits.h> #include <string.h> #endif |
The prototypes for bzero(), bcopy(), etc. are located in string.h instead. The #define for PATH_MAX is in limits.h.
IRIS Performer 2.3 for Linux is only available for Intel x86-based systems. The little-endian structure of the Intel x86 architecture is the opposite of that of big-endian MIPS-based IRIX; so, any code or data that assumes big-endian operation will fail sometimes in an unpredictable manner.
A typical case where endianness issues are seen is when using data or retained database files that were generated on IRIX or other big-endian systems. The database loaders shipped with IRIS Performer 2.3 for Linux have been modified to automatically identify such files and correct the byte ordering in the file, accordingly. If you have implemented your own file loaders, you should make similar changes.
See the source code of the bin or pfb loaders shipped in /usr/share/Performer/src/lib/libpfdb/libpfbin/pfbin.c and /usr/share/Performer/src/lib/libpfdb/libpfpfb/pfpfb.c for a simple and a complex example of the changes necessary. In the case of bin format, the assumption is made that all input files will contain big-endian data so a byte flip of integer data is always necessary. In the case of pfb format, a more sophisticated approach is taken that detects the endianness of the data file by comparing a header key to its representation in the native format. If they match, no changes are necessary. If they are in the opposite byte order, then an alternate fread function is used that will swap the bytes.
Endianness issues arise in many other cases, such as when defining RGB color values in a single 32-bit variable. For example, the following code from IRIX defines an array of eight RGB color values:
static const uint colors[MAX_SIZE] =
{
0xff080000,
0xff190100,
0xff2a0100,
0xff3b0100,
0xff4c0200,
0xff5d0240,
0xff6e0280,
0xff7f02c0
};
|
This would need to be changed in Linux (preferably also using an #ifdef __linux__ / #endif preprocessor directive so that the code could still be shared between the two platforms) to the following:
static const uint colors[MAX_SIZE] =
{
0x000008ff,
0x000119ff,
0x00012aff,
0x00013bff,
0x00024cff,
0x40025dff,
0x80026eff,
0xc0027fff
};
|
The compilers shipped with most Linux distributions do not automatically zero variables and pointers as they are declared. This may expose hidden bugs in your code; so, you should take extra care to set variables before using them. As an example, var needs to be initialized to NULL in the code below:
void myfunc()
{
static pfGroup *var;
if (!var)
{
/* initialize var */
}
/* use var */
}
|
A good C program checker such as lint may help you to detect such bugs.
Certain IRIX functionality or OpenGL functionality specific to SGI IRIX-based systems is not available on Linux platforms and, likewise, certain functionality from IRIS Performer 2.2 on IRIX is not yet available in IRIS Performer 2.3 for Linux.
This section is an overview of the features commonly used in IRIX-based IRIS Performer applications that are not supported in this release. Results stemming from the use of such features is undefined.
Ignoring the settings your program has made, in many cases IRIS Performer 2.3 for Linux will add prominent warning or informational messages to your program output if unsupported functionality is utilized and then continue normally . However, in other cases your program will fail or behave in an unexpected manner.
The following are general aspects of IRIS Performer functionality not supported in this release:
Multiprocessing (forked CULL, DRAW, X Input, DBASE, COMPUTE, ISECT, threaded CULL, threaded LPOINT, etc.) is not supported. Only PFMP_APPCULLDRAW mode is available.
Multipipe operation (pfMultipipe, pfHyperpipe, etc.) is not supported. Only a single graphics pipeline can be utilized.
Shared arenas (pfGetSharedArena) and related functions are not supported. pfGetSharedArena() will always return NULL.
The following are SGI-specific OpenGL features or IRIX-specific functionality that are not supported in the current release:
Data pools (pfDataPool)
Real-Time processor control (pfuProcessManager)
Video retrace timing control (pfVClock)
Clip textures (pfClipTexture, pfMPClipTexture, pfImageTile, etc.)
Antialiasing (pfAntialias)
Projected or shadowed light sources (part of pfLightSource)
Dynamic video resize (pfVideoChannel)
Calligraphic light points (pfCalligraphic)
SGI Video Channel Extensions (pfVideoChannel)
Direct file I/O (pfFile)
IRIS Performer 2.3 for Linux only operates in a single-process model, which allows certain poor coding practices to be utilized with regards to program structure. However, a future release of IRIS Performer for Linux will support the multi-process functionality of the pfPipe object for forked cull, draw, intersections, database paging, and asynchronous compute functionality familiar to IRIX users. In preparation for these future releases, here are some very important things to remember so that your new application will work when multiprocessed. For more detailed information on proper multiprocess-ready coding practices, refer to the IRIS Performer Programmer's Guide.
When allocating any data that must be shared by the APP, ISECT, DBASE, COMPUTE, CULL, or DRAW stages of the pipeline, such as geometry data, be certain to allocate them from the shared arena and with functionality that uses pfMalloc(). Note this example:
pfGeoSet *gs = pfNewGSet(pfGetSharedArena()); |
Any actual pointers to shared memory that should be visible from the different pipeline stages should be allocated between pfInit() and pfConfig(). Data allocated to global variables initialized after pfConfig() will only be visible to the process that did the allocation. This is a correct example:
SharedData *s; pfInit(); pfMultiprocess(PFMP_DEFAULT); /* allocate shared data before fork()'ing parallel processes */ s = (SharedData*) pfMalloc(sizeof(SharedData), pfGetSharedArena()); pfConfig(); |
Only issue OpenGL commands in a pipeline initialization callback, channel draw callback, or node draw callback. When multiprocessing, the draw callbacks will be properly executed in the DRAW process, which is the only process with a valid GLX context.