Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

321 lines
16 KiB

  1. -------------------------------------------------------------------------------
  2. GLS: Stream encoding for OpenGL commands
  3. Craig Dunwoody
  4. [email protected]
  5. -------------------------------------------------------------------------------
  6. -------------------------------------------------------------------------------
  7. Introduction
  8. -------------------------------------------------------------------------------
  9. GLS is a facility for encoding and decoding streams of 8-bit bytes
  10. that represent sequences of OpenGL (henceforth, "GL") commands. The
  11. GLS specification has two components:
  12. 1. A set of three byte stream encodings for GL and GLS commands
  13. (human-readable text, big-endian binary, and little-endian binary).
  14. The three encodings are semantically identical, differing only in syntax.
  15. GLS byte streams can therefore be converted freely among the three
  16. encodings without loss of information.
  17. 2. An API that provides commands for encoding and decoding GLS byte streams.
  18. This API is not formally an extension of the GL API. Like the GLU API,
  19. the GLS API is designed to be implemented in an optional, standalone
  20. client-side subroutine library that is separate from the subroutine
  21. library that implements the GL API.
  22. The GLS encodings and API are platform independent and window system
  23. independent. In particular, the GLS encodings are not tied to the
  24. encoding used in the GLX extension to the X Window System protocol.
  25. GLS is designed to work equally well in Unix/X, Windows, and other
  26. environments.
  27. It is expected that GLS will prove useful to the GL community in a
  28. wide range of applications, including:
  29. - GL command streams for resolution-independent storage, interchange,
  30. viewing, and printing of pictures
  31. - GL command files for persistent storage of textures, display lists,
  32. images, etc.
  33. - GL trace streams for debuggers, performance analyzers, and simulators
  34. - GL test-vector streams for correctness testing of GL
  35. implementations
  36. - Picture-level benchmarking using GL command files to represent
  37. pictures
  38. - Transfer of GL commands between application processes via byte
  39. stream connections
  40. - Client-side display lists that can contain client callbacks
  41. Some of these applications will require the definition and
  42. implementation of higher-level APIs that are more convenient to use
  43. than the GLS API. The GLS API design is an attempt to provide basic
  44. encoding and decoding services in such a way that higher-level
  45. services can efficiently be built on top.
  46. -------------------------------------------------------------------------------
  47. Status
  48. -------------------------------------------------------------------------------
  49. SGI is developing a GLS specification document for presentation to the
  50. GL ARB as a proposed standard for the GL community. As soon as the
  51. first draft of this document is complete, SGI will distribute it to
  52. all interested parties for comment.
  53. SGI has developed GLSREF, a portable ISO C reference implementation of
  54. the GLS API. SGI has also developed a simple utility program called
  55. glscat that makes it easy to convert a GLS byte stream from one
  56. encoding to another.
  57. -------------------------------------------------------------------------------
  58. GLS Encodings
  59. -------------------------------------------------------------------------------
  60. Each of the GLS encodings is capable of representing all GL commands,
  61. without exception. This includes "get" commands that return data to
  62. the GL client and all other commands that are not allowed in GL
  63. display lists.
  64. In addition to GL commands, a subset of the commands in the GLS API
  65. are "encodable", meaning that they can be represented in GLS streams.
  66. These GLS commands make it possible to encode various kinds of non-GL
  67. data in GLS streams.
  68. The binary encodings represent most commands as 16 bits of opcode,
  69. followed by 16 bits of word-count, followed by zero or more 32-bit
  70. words of argument data. An alternate encoding is used for opcodes
  71. larger than 65535 and commands that require more than 65535 32-bit
  72. words to encode.
  73. The text encoding looks like C source code, except that array
  74. arguments are represented as lists of elements delimited by braces.
  75. Enumerants are represented symbolically. An example of a GLS text
  76. stream:
  77. ---------------------------------------------------------------------------
  78. glsBeginGLS(1, 0); # arguments are major, minor GLS version
  79. glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
  80. glBegin(GL_POINTS);
  81. glVertex3fv({1.2, 3.4, 5.6});
  82. glEnd();
  83. glsEndGLS();
  84. ---------------------------------------------------------------------------
  85. All GLS streams begin with the encodable GLS command glsBeginGLS() and
  86. end with the encodable GLS command glsEndGLS(). The concatenation of
  87. two valid GLS streams is always a valid GLS stream, even if the two
  88. streams do not have the same GLS encoding.
  89. -------------------------------------------------------------------------------
  90. GLS API
  91. -------------------------------------------------------------------------------
  92. This section provides a brief overview of the core of the GLS API.
  93. ---------------------------------------------------------------------------
  94. GLuint glsGenContext(void);
  95. void glsDeleteContext(GLuint inContext);
  96. void glsContext(GLuint inContext); /* set thread's current GLS context */
  97. ---------------------------------------------------------------------------
  98. Like GL, GLS defines a state machine. A GLS context is
  99. an instantiation of this state machine. GLS contexts and GL
  100. contexts are completely independent. Like GLU state, GLS contexts
  101. are stored entirely on the client side of the GL client-server
  102. connection. Each GLS context has a nonzero name of type GLuint.
  103. Each GLS command is classified as either global, immediate, or encodable:
  104. ---------------------------------------------------------------------------
  105. Category Uses GLS context state Encodable
  106. ---------------------------------------------------------------------------
  107. Global
  108. Immediate X
  109. Encodable X X
  110. ---------------------------------------------------------------------------
  111. The commands glsGenContext(), glsDeleteContext(), and glsContext() are
  112. global. All of the GLS commands described in the remainder of this
  113. section are non-global.
  114. Each client thread has a state variable that always contains either
  115. zero (the initial value) or the name of the thread's current GLS
  116. context. If the value is zero, all non-global GLS commands are no-ops,
  117. and non-global GLS commands that return a value will return zero. If the
  118. value is nonzero, all non-global GLS commands use the state in the
  119. issuing thread's current GLS context. At any given instant, a GLS
  120. context may be current to at most one thread.
  121. ---------------------------------------------------------------------------
  122. GLboolean glsBeginCapture(
  123. const GLubyte *inStreamName,
  124. GLSenum inStreamType,
  125. GLbitfield inWriteFlags
  126. );
  127. void glsEndCapture(void);
  128. ---------------------------------------------------------------------------
  129. Between a glsBeginCapture() command and the following glsEndCapture()
  130. command, the current GLS context is in "capture mode". In capture mode,
  131. all GL commands will be captured by GLS instead of being sent
  132. directly to GL and executed, and all encodable GLS commands will be
  133. captured instead of being sent directly to GLS and executed.
  134. The command glsBeginCapture() opens a stream for writing and then encodes
  135. the command glsBeginGLS(). The command glsEndCapture() encodes the
  136. command glsEndGLS() and then closes the currently open GLS stream.
  137. inStreamType is one of:
  138. GLS_CONTEXT /* in-memory stream stored in GLS context */
  139. GLS_BINARY_LSB_FIRST /* binary stream, little-endian */
  140. GLS_BINARY_MSB_FIRST /* binary stream, big-endian */
  141. GLS_TEXT /* text stream */
  142. inWriteFlags is zero or more of:
  143. GLS_WRITE_APPEND_BIT /* if stream exists, don't truncate */
  144. If inStreamType is GLS_CONTEXT, the command glsBeginCapture() will open
  145. an in-memory stream named inStreamName that is stored in the current GLS
  146. context. Within the constraints of available memory, a GLS context can
  147. contain an arbitrary number of named GLS_CONTEXT streams. GLS_CONTEXT
  148. streams can be thought of as client-side display lists that complement
  149. the server-side display lists provided by core GL.
  150. If inStreamType is GLS_BINARY_LSB_FIRST, GLS_BINARY_MSB_FIRST, or GLS_TEXT,
  151. the name of the opened stream is formed by appending inStreamName to a
  152. write-prefix string that is stored in the current GLS context. The
  153. command glsWritePrefix() (not described here) can be used to replace the
  154. value of the write-prefix string.
  155. If inStreamType is GLS_BINARY_LSB_FIRST, GLS_BINARY_MSB_FIRST, or GLS_TEXT,
  156. and inStreamName is not the empty string (""), the command
  157. glsBeginCapture() will use the standard C library command fopen() to create
  158. a write channel of type FILE*.
  159. If inStreamType is GLS_BINARY_LSB_FIRST, GLS_BINARY_MSB_FIRST, or GLS_TEXT,
  160. and inStreamName is the empty string, the command glsBeginCapture() will
  161. use a default write channel of type FILE* that is stored in the current
  162. GLS context (initial value: stdout). The command glsChannel() (not
  163. described here) can be used to replace the value of the default write
  164. channel.
  165. If inStreamType is GLS_BINARY_LSB_FIRST, GLS_BINARY_MSB_FIRST, or GLS_TEXT,
  166. and inStreamName is the empty string, and the GLS client has used the
  167. command glsWriteFunc() (not described here) to specify a write callback
  168. function, that function will be used in place of the standard C library
  169. function fwrite() when bytes are to be written to the stream.
  170. ---------------------------------------------------------------------------
  171. void glsCaptureFlags(GLSopcode inOpcode, GLbitfield inFlags);
  172. ---------------------------------------------------------------------------
  173. A GLS context contains two capture-mode control bits for each opcode:
  174. GLS_CAPTURE_WRITE_BIT /* write command to open stream */
  175. GLS_CAPTURE_EXECUTE_BIT /* execute command */
  176. The command glsCaptureFlags() allows the GLS client to specify on a
  177. per-opcode basis whether a captured GL or encodable GLS command
  178. should be written to the open stream and/or executed by GL or GLS.
  179. ---------------------------------------------------------------------------
  180. GLSenum glsCallStream(const GLubyte *inStreamName);
  181. ---------------------------------------------------------------------------
  182. This command decodes a named GLS stream (which may be in any GLS encoding)
  183. and issues the commands in the stream to GL and GLS, just as if those
  184. commands had been issued directly in immediate mode by the calling thread.
  185. The command returns the type of the stream.
  186. If inStreamName is the name of a GLS_CONTEXT in-memory stream stored in
  187. the current GLS context, the command glsCallStream() will decode that
  188. stream. Otherwise, the command searches for an external stream to decode.
  189. If inStreamName is not the empty string (""), a sequence of potential
  190. external stream names is formed. The first names in the sequence are
  191. formed by appending inStreamName to each of the strings in a list of
  192. read-prefix strings that is stored in the current GLS context. The command
  193. glsReadPrefix() (not described here) can be used to modify the contents
  194. of the read-prefix string list. The last name in the sequence is formed
  195. by appending inStreamName to the write-prefix string.
  196. Beginning with the first potential external stream name, the command
  197. glsCallStream() tries each successive name until either a readable
  198. stream is found or all of the names have been tried. For each name,
  199. the command fopen() is issued with the name as an argument, in an attempt
  200. to create a read channel of type FILE*.
  201. If inStreamName is the empty string, the command glsCallStream() will use
  202. a default read channel of type FILE* that is stored in the current GLS
  203. context (initial value: stdin). The command glsChannel() (not described
  204. here) can be used to replace the value of the default read channel.
  205. If inStreamName is the empty string, and the GLS client has used the
  206. command glsReadFunc() (not described here) to specify a read callback
  207. function, that function will be used in place of the standard C library
  208. function fread() when bytes are to be read from the stream.
  209. The command glsCallStream() is encodable. When a GLS decoder reads
  210. this command from a GLS stream, the decoder recursively decodes the GLS
  211. stream named in the command. As a result, GLS streams provide the same
  212. embedding capability on the client side that GL display lists provide
  213. on the server side.
  214. ---------------------------------------------------------------------------
  215. void glsCommandFunc(GLSopcode inOpcode, GLScommandFunc inFunc);
  216. ---------------------------------------------------------------------------
  217. This command registers the client callback function inFunc for the GL
  218. or encodable GLS command designated by inOpcode. When a GLS decoder
  219. reads this command from a GLS stream, the decoder will call inFunc instead
  220. of issuing the command.
  221. Command arguments are passed to inFunc just as they would have been passed
  222. to the function that implements the GL or GLS command. The function
  223. inFunc is free to perform arbitrary computations, including the issuing
  224. of GL and GLS commands.
  225. Certain encodable GLS commands (not described here) are provided for
  226. the sole purpose of encoding arrays of arbitrary client data as command
  227. arguments in a GLS stream. If a GLS client provides a callback function
  228. for one or more of these encodable GLS commands, the client can use
  229. GLS_CONTEXT in-memory streams to create client-side display lists that
  230. contain client callbacks. This functionality is present in IrisGL but
  231. not in core GL.
  232. ---------------------------------------------------------------------------
  233. void glsUnsupportedCommand(void);
  234. ---------------------------------------------------------------------------
  235. The GLS encodings and API are designed to handle GL extensions.
  236. Extension commands are encoded and decoded in the same way as GL 1.0
  237. commands. Extension opcodes for the binary encodings will be
  238. allocated on demand in blocks of 16 from a registry maintained by SGI.
  239. To guarantee successful interchange of GLS streams, it is required
  240. that any GLS implementation be able to read any GLS stream, even if
  241. the GLS stream contains extension commands that are not recognized by
  242. the GLS implementation.
  243. If a GLS decoder reads from a GLS stream a command that it cannot decode,
  244. the decoder issues the encodable GLS command glsUnsupportedCommand().
  245. The command glsCommandFunc() can be used to register a client callback
  246. function for the command glsUnsupportedCommand().
  247. -------------------------------------------------------------------------------
  248. Implementation Considerations
  249. -------------------------------------------------------------------------------
  250. Platform-specific mechanisms are required to implement the capture of
  251. GL commands without compromising immediate-mode GL performance when
  252. GLS is not in capture mode. Otherwise, GLSREF is quite portable.
  253. -------------------------------------------------------------------------------
  254. End
  255. -------------------------------------------------------------------------------