------------------------------------------------------------------------------- Porting GLSREF to a new platform ------------------------------------------------------------------------------- GLSREF is a reference implementation of the GLS API. The primary goals of GLSREF are as follows: - Correct runtime behavior - Portability to many platforms The following are NOT primary goals of GLSREF: - Maximum execution speed - Minimum resource usage - Portability to all platforms Although GLSREF is strictly a reference implementation of the GLS API, and not a sample implementation or a product-quality implementation, the task of creating a product-quality implementation of the GLS API on a specific platform is likely to be significantly easier if GLSREF, rather than a clean sheet of paper, is used as the starting point. There are many possible product-quality implementations of the GLS API. The only constraint on all such implementations is that their runtime behavior (as observed via the GLS API) must be indistinguishable (except for execution speed and resource usage) from the runtime behavior of GLSREF. As explained below, developing a product-quality implementation of the GLS API requires the addition of hooks to the underlying GL implementation. ------------------------------------------------------------------------------- Assumptions ------------------------------------------------------------------------------- GLSREF makes the following assumptions about the underlying platform. Bringing up GLSREF on a platform that matches these assumptions should involve relatively little effort. Bringing up GLSREF on a platform that does not match these assumptions is likely to require significant modifications to GLSREF. - The implementation of the C language and standard library conforms to the ISO C standard. - Two's complement representation is used for all signed integers. - The representation of all floating-point numbers conforms to the IEEE 754-1985 standard. - The implementation of GL conforms to the OpenGL standard. - The sizes of GL data types are as follows: GLbitfield 32 bits GLboolean 8 bits GLbyte 8 bits GLclampd 64 bits GLclampf 32 bits GLdouble 64 bits GLenum 32 bits GLfloat 32 bits GLint 32 bits GLlong 64 bits GLshort 16 bits GLsizei 32 bits GLubyte 8 bits GLuint 32 bits GLulong 64 bits GLushort 16 bits - A runtime linking mechanism is available. To date, GLSREF has been brought up on platforms that support one of the following runtime linking mechanisms: - AIX Shared Archives (.a) - HP-UX Shared Libraries (.sl) - SVR4 Dynamic Shared Objects (.so) - Windows NT Dynamic Link Libraries (.dll) SGI has no plans to change this set of assumptions. The test programs supplied with GLSREF assume that the GL commands glGetIntegerv() and glPixelStorei() are no-ops if there is no current GL rendering context. This assumption obviates the need for the test programs to create GL rendering contexts. This in turn makes the test programs more portable. ------------------------------------------------------------------------------- Bringing up GLSREF on a new platform ------------------------------------------------------------------------------- Platform dependencies in GLSREF are encapsulated in the files lib/platform.[ch]. These files contain platform specific code for a number of platforms. The #if/#endif conditional compilation mechanism is used to select code for a specific platform. Conditional compilation can also be used to build different GLS implementations for a single platform. For example, the files lib/platform.[ch] contain platform specific code for both the portable IRIX version of GLSREF (which will run on any system running IRIX Release 5.3 or later) and the product-quality IRIX implementation of the GLS API (which contains generated source code that is subject to change with each IRIX release). Conditional compilation determines which IRIX implementation is built. Use the following steps as a guide to bringing up GLSREF on a new platform. - Create .mak files for your platform, using the supplied makefiles as a guide. - Add the following symbol definition to your C compilation command line: -D__GLS_PLATFORM_=1 If your platform has "big-endian" byte order, also add to your C compilation command line: -D__GLS_MSB_FIRST=1 - For ease of initial bringup, add the following to lib/platform.h, using the supplied platform specific sections as a guide: #if __GLS_PLATFORM_ #define __GL_LIB_NAME "" #define __GLS_FAKE_FINITE_FUNC 1 #define __GLS_FAKE_MUTEX 1 #define __GLS_FAKE_THREAD_LOCAL_STORAGE 1 #define __GLS_FAKE_TRUNCATE_FUNC 1 #define __GLS_GL_DISPATCH 1 #define __GLS_PLATFORM "" #endif /* __GLS_PLATFORM_ */ If your platform supports SVR4 Dynamic Shared Objects, also add to this section: #define __GLS_GL_DISPATCH_DSO 1 - Add a platform specific section to lib/platform.c that contains code to operate your platform's dynamic linking mechanism. Use the supplied platform specific sections as a guide. - Once you have successfully brought up an initial version of GLSREF on your platform, use the supplied platform specific code as a guide to determine if you can implement the following: - use of alloca() for decode functions - finite function for 64-bit floating point numbers - mutual exclusion (critical sections) - thread local storage - file truncate function - support for 64-bit integers None of these things is required by the ISO C standard. If you can implement some or all of them, make appropriate modifications to your platform specific #defines in lib/platform.h. - Once you have successfully brought up GLSREF on your platform, please send SGI a set of diffs containing the changes you had to make. If your platform matches the assumptions listed above, SGI will make a good-faith effort to incorporate your changes into the master GLSREF sources. This will simplify your integration task when SGI produces future GLSREF releases. If your platform does not match the assumptions listed above, SGI will consider incorporating your changes into the master GLSREF sources, but reserves the right to choose not to incorporate your changes, especially if those changes do not enhance portability to any other platform. ------------------------------------------------------------------------------- Developing a product-quality GLS implementation based on GLSREF ------------------------------------------------------------------------------- The main difficulty in using GLSREF as the basis for a product-quality implementation of the GLS API arises from the fact that every GL command must be captured by GLS when the issuing thread has a current GLS context and that GLS context is in capture mode. As shipped, GLSREF achieves this effect by providing a wrapper function for each GL command. Each wrapper function has the same name as the function that implements the corresponding GL command. If a thread has a current GLS context and that context is in capture mode, the wrapper functions redirect to GLS all GL commands issued by that thread. Otherwise, the wrapper functions pass directly to GL all GL commands issued by that thread. GLSREF uses the underlying platform's runtime linking mechanism to obtain the addresses of the functions that implement GL commands. The wrapper technique makes it possible to bring up GLSREF quickly on a platform that matches the assumptions listed above. On the other hand, the wrapper technique has the major disadvantage that linking an application with the GLSREF library will degrade that application's immediate-mode GL performance, even when the wrapper functions are passing all GL commands directly to GL. As a result, GLSREF is not suitable for shipping unmodified to customers as a product. In order to make it possible for applications to link with the GLSREF library without affecting immediate-mode GL performance, it is necessary to modify GLSREF to not use the wrapper technique. This in turn requires modifications to the underlying GL implementation. Specifically, it is necessary to add hooks to the underlying GL command-dispatch mechanism that cause a GL command to be redirected to GLS if the issuing thread has a current GLS context and that GLS context is in capture mode. For an example of how this can be done, see the files lib/platform.c and lib/g_irix.c. The command __glsUpdateDispatchTables() enables and disables the underlying GL dispatch table override mechanism, and the commands __glsBeginCaptureExec() and __glsEndCaptureExec() are used to temporarily disable the underlying GL dispatch table override mechanism for a single command. This is necessary when a GLS context is in capture mode and either generates a glGet() command or captures a GL command whose capture-flag variable has the bit GLS_CAPTURE_EXECUTE_BIT set. ------------------------------------------------------------------------------- End -------------------------------------------------------------------------------