1Name 2 3 NV_framebuffer_blit 4 5Name Strings 6 7 GL_NV_framebuffer_blit 8 9Contributors 10 11 Contributors to EXT_framebuffer_blit, ARB_framebuffer_object 12 and ANGLE_framebuffer_blit 13 Greg Roth, NVIDIA 14 Xi Chen, NVIDIA 15 16Contact 17 18 Mathias Heyer, NVIDIA Corporation (mheyer 'at' nvidia.com) 19 20Status 21 22 Complete 23 24Version 25 26 Last Modified Date: 03 Mar 2015 27 Author Revision: 06 28 29Number 30 31 OpenGL ES Extension #142 32 33Dependencies 34 35 OpenGL ES 2.0 is required. 36 37 The extension is written against the OpenGL ES 2.0.25 specification. 38 39 EXT_sRGB affects the definition of this extension. 40 41 EXT_color_buffer_half_float affects the definition of this extension 42 43 EXT_discard_framebuffer affects the definition of this extension 44 45 NV_fbo_color_attachments affects the definition of this extension 46 47 NV_framebuffer_multisample affects the definition of this extension 48 49 NV_read_buffer affects the definition of this extension 50 51 NV_draw_buffers affects the definition of this extension 52 53 This extension interacts with OpenGL ES 3.0 and later versions. 54 55Overview 56 57 This extension modifies OpenGL ES 2.0 by splitting the 58 framebuffer object binding point into separate DRAW and READ 59 bindings. This allows copying directly from one framebuffer to 60 another. In addition, a new high performance blit function is 61 added to facilitate these blits and perform some data conversion 62 where allowed. 63 64New Procedures and Functions 65 66 void BlitFramebufferNV(int srcX0, int srcY0, int srcX1, int srcY1, 67 int dstX0, int dstY0, int dstX1, int dstY1, 68 bitfield mask, enum filter); 69 70New Tokens 71 72 Accepted by the <target> parameter of BindFramebuffer, 73 CheckFramebufferStatus, FramebufferTexture2D, 74 FramebufferRenderbuffer, and GetFramebufferAttachmentParameteriv: 75 76 READ_FRAMEBUFFER_NV 0x8CA8 77 DRAW_FRAMEBUFFER_NV 0x8CA9 78 79 Accepted by the <pname> parameters of GetIntegerv and GetFloatv: 80 81 DRAW_FRAMEBUFFER_BINDING_NV 0x8CA6 // alias FRAMEBUFFER_BINDING 82 READ_FRAMEBUFFER_BINDING_NV 0x8CAA 83 84 85Additions to Chapter 3 of the OpenGL ES 2.0.25 Specification 86(Rasterization) 87 88 Change the last paragraph of section 3.7.2 to: 89 90 "Calling CopyTexImage2D or CopyTexSubImage2D will result in an 91 INVALID_FRAMEBUFFER_OPERATION error if the object bound to 92 READ_FRAMEBUFFER_BINDING_NV is not framebuffer complete 93 (see section 4.4.5)." 94 95 96 Additions to Chapter 4 of the OpenGL ES 2.0.25 Specification 97 (Per-Fragment Operations and the Frame Buffer) 98 99 Change the first word of Chapter 4 from "The" to "A". 100 101 Replace the last paragraph of the Introduction of Chapter 4: 102 103 "The GL has two active framebuffers; the draw framebuffer is the 104 destination for rendering operations, and the read framebuffer is 105 the source for readback operations. The same framebuffer may be used 106 for both drawing and reading. Section 4.4.1 describes the mechanism 107 for controlling framebuffer usage. 108 109 The default framebuffer is initially used as the draw and read 110 framebuffer and the initial state of all provided bitplanes is 111 undefined. The format and encoding of buffers in the draw and read 112 framebuffers can be queried as described in section 6.1.7." 113 114 Modify the first sentence of the last paragraph of section 4.1.1: 115 116 "While an application-created framebuffer object is bound to 117 DRAW_FRAMEBUFFER_NV, the pixel ownership test always passes." 118 119 120 In section 4.3.1 (Reading Pixels), replace the following sentence: 121 122 "The implementation-chosen format may vary depending on the format 123 of the currently bound rendering surface." 124 125 with: 126 127 "The implementation chosen format may vary depending on the format 128 of the selected READ_BUFFER_NV of the currently bound read 129 framebuffer (READ_FRAMEBUFFER_BINDING_NV)." 130 131 Add to section 4.3.1 (Reading Pixels) right before the subsection 132 "Obtaining Pixels from the Framebuffer": 133 134 "Calling ReadPixels generates INVALID_FRAMEBUFFER_OPERATION if 135 the object bound to READ_FRAMEBUFFER_BINDING_NV is not "framebuffer 136 complete" (section 4.4.5)." 137 138 139 In section 4.3.1, after the definition of ReadBufferNV, replace 140 141 "FRAMEBUFFER_BINDING" with "READ_FRAMEBUFFER_BINDING_NV", 142 so that ReadBufferNV always refers to the current read framebuffer. 143 144 145 Add section 4.3.3 Copying Pixels: 146 147 "BlitFramebufferNV transfers a rectangle of pixel values from one 148 region of the read framebuffer to another in the draw framebuffer. 149 150 BlitFramebufferNV(int srcX0, int srcY0, int srcX1, int srcY1, 151 int dstX0, int dstY0, int dstX1, int dstY1, 152 bitfield mask, enum filter); 153 154 <mask> is the bitwise OR of a number of values indicating which 155 buffers are to be copied. The values are COLOR_BUFFER_BIT, 156 DEPTH_BUFFER_BIT, and STENCIL_BUFFER_BIT, which are described in 157 section 4.2.3. The pixels corresponding to these buffers are 158 copied from the source rectangle, bound by the locations (srcX0, 159 srcY0) and (srcX1, srcY1), to the destination rectangle, bound by 160 the locations (dstX0, dstY0) and (dstX1, dstY1). The lower bounds 161 of the rectangle are inclusive, while the upper bounds are 162 exclusive. 163 164 When the color buffer is transferred, values are taken from the read 165 buffer of the read framebuffer and written to each of the draw 166 buffers of the draw framebuffer. 167 168 The actual region taken from the read framebuffer is limited to the 169 intersection of the source buffers being transferred, which may 170 include the color buffer selected by the read buffer, the depth 171 buffer, and/or the stencil buffer depending on <mask>. The actual 172 region written to the draw framebuffer is limited to the 173 intersection of the destination buffers being written, which may 174 include multiple draw buffers, the depth buffer, and/or the stencil 175 buffer depending on <mask>. Whether or not the source or destination 176 regions are altered due to these limits, the scaling and offset 177 applied to pixels being transferred is performed as though no such 178 limits were present. 179 180 If the source and destination rectangle dimensions do not match, 181 the source image is stretched to fit the destination rectangle. 182 <filter> must be LINEAR or NEAREST and specifies the method of 183 interpolation to be applied if the image is stretched. LINEAR 184 filtering is allowed only for the color buffer; if <mask> includes 185 DEPTH_BUFFER_BIT or STENCIL_BUFFER_BIT, and filter is not NEAREST, 186 no copy is performed and an INVALID_OPERATION error is generated. 187 If the source and destination dimensions are identical, no filtering 188 is applied. If either the source or destination rectangle specifies 189 a negative dimension, the image is reversed in the corresponding 190 direction. If both the source and destination rectangles specify a 191 negative dimension for the same direction, no reversal is performed. 192 If a linear filter is selected and the rules of LINEAR sampling 193 (see section 3.7.7) would require sampling outside the bounds of a 194 source buffer, it is as though CLAMP_TO_EDGE texture sampling were 195 being performed. If a linear filter is selected and sampling would 196 be required outside the bounds of the specified source region, but 197 within the bounds of a source buffer, the implementation may choose 198 to clamp while sampling or not. 199 200 If the source and destination buffers are identical, and the source 201 and destination rectangles overlap, the result of the blit operation 202 is undefined. 203 204 When values are taken from the read buffer, if the value of 205 FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING for the framebuffer attachment 206 corresponding to the read buffer is sRGB (see section 6.1.13), the 207 red, green, and blue components are converted from the non-linear 208 sRGB color space as described in section 3.7.14. 209 210 When values are written to the draw buffers, blit operations bypass the 211 fragment pipeline. The only fragment operations which affect a blit are the 212 pixel ownership test, the scissor test, and sRGB conversion 213 (see section 3.7.14). Additionally color, depth, and stencil masks 214 (see section 4.2.2) are ignored. 215 216 If a buffer is specified in <mask> and does not exist in both the 217 read and draw framebuffers, the corresponding bit is silently 218 ignored. 219 220 If the color formats of the read and draw framebuffers do not 221 match, and <mask> includes COLOR_BUFFER_BIT, the pixel groups are 222 converted to match the destination format as in CopyTexImage. 223 224 However, colors are clamped only if all draw color buffers have fixedpoint 225 components. Format conversion is not supported for all data types, and an 226 INVALID_OPERATION error is generated under any of the following conditions: 227 228 * The read buffer contains fixed-point or floating-point values and 229 any draw buffer contains neither fixed-point nor floating-point values. 230 231 Calling BlitFramebufferNV will result in an 232 INVALID_FRAMEBUFFER_OPERATION_EXT error if the objects bound to 233 DRAW_FRAMEBUFFER_BINDING_NV and READ_FRAMEBUFFER_BINDING_NV are 234 not "framebuffer complete" (section 4.4.4.2)." 235 236 Calling BlitFramebufferNV will result in an INVALID_OPERATION 237 error if <mask> includes DEPTH_BUFFER_BIT or STENCIL_BUFFER_BIT 238 and the source and destination depth and stencil buffer formats do 239 not match. 240 241 If SAMPLE_BUFFERS for the read framebuffer is greater than zero and 242 SAMPLE_BUFFERS for the draw framebuffer is zero, the samples 243 corresponding to each pixel location in the source are converted to 244 a single sample before being written to the destination. 245 246 If SAMPLE_BUFFERS for the read framebuffer is zero and 247 SAMPLE_BUFFERS for the draw framebuffer is greater than zero, the 248 value of the source sample is replicated in each of the destination 249 samples. 250 251 If SAMPLE_BUFFERS for both the read and draw framebuffers are 252 greater than zero, and the values of SAMPLES for the read and draw 253 framebuffers are identical, the samples are copied without 254 modification from the read framebuffer to the draw framebuffer. 255 Otherwise, no copy is performed and an INVALID_OPERATION error is 256 generated. Note that the samples in the draw buffer are not 257 guaranteed to be at the same sample location as the read buffer, 258 so rendering using this newly created buffer can potentially 259 have geometry cracks or incorrect antialiasing. This may occur 260 if the sizes of the framebuffers do not match, if the 261 formats differ, or if the source and destination rectangles are 262 not defined with the same (X0,Y0) and (X1,Y1) bounds. 263 264 If SAMPLE_BUFFERS for either the read framebuffer or 265 draw framebuffer is greater than zero, no copy is performed and an 266 INVALID_OPERATION error is generated if the dimensions of the source 267 and destination rectangles provided to BlitFramebuffer are not 268 identical, or if the formats of the read and draw framebuffers are 269 not identical. 270 271 272 Modify the beginning of section 4.4.1 (Binding and Managing 273 Framebuffer Objects): 274 275 The default framebuffer for rendering and readback operations is 276 provided by the windowing system. In addition, named framebuffer 277 objects can be created and operated upon. The namespace for 278 framebuffer objects is the unsigned integers, with zero reserved 279 by the GL for the default framebuffer. 280 281 A framebuffer object is created by binding an unused name to 282 DRAW_FRAMEBUFFER_NV or READ_FRAMEBUFFER_NV. The binding is 283 effected by calling 284 285 void BindFramebuffer( enum target, uint framebuffer ); 286 287 with <target> set to the desired framebuffer target and 288 <framebuffer> set to the unused name. The resulting framebuffer 289 object is a new state vector. There are MAX_COLOR_ATTACHMENTS_NV 290 color attachment points, plus one each for the depth and stencil 291 attachment points. 292 293 BindFramebuffer may also be used to bind an existing framebuffer 294 object to DRAW_FRAMEBUFFER_NV and/or READ_FRAMEBUFFER_NV. If the 295 bind is successful no change is made to the state of the bound 296 framebuffer object and any previous binding to <target> is broken. 297 298 If a framebuffer object is bound to DRAW_FRAMEBUFFER_NV or READ_- 299 FRAMEBUFFER_NV, it becomes the target for rendering or readback 300 operations, respectively, until it is deleted or another framebuffer 301 is bound to the corresponding bind point. Calling BindFramebuffer 302 with <target> set to FRAMEBUFFER binds <framebuffer> to both read 303 and draw targets. 304 305 While a framebuffer object is bound, OpenGL ES operations on the 306 target to which it is bound affect the images attached to the bound 307 framebuffer object, and queries of the target to which it is bound 308 return state from the bound object. Queries of the values specified 309 in table 6.21 (Implementation Dependent Pixel Depths) are derived 310 from the framebuffer object bound to DRAW_FRAMEBUFFER_NV with the 311 exception of IMPLEMENTATION_COLOR_READ_TYPE and IMPLEMENTATION_- 312 COLOR_READ_FORMAT, which are derived from the framebuffer object 313 bound to READ_FRAMEBUFFER_NV. 314 315 The initial state of DRAW_FRAMEBUFFER_NV and READ_FRAMEBUFFER_NV 316 refers to the default framebuffer. In order that access to the 317 default framebuffer is not lost, it is treated as a framebuffer 318 object with the name of zero. The default framebuffer is therefore 319 rendered to and read from while zero is bound to the corresponding 320 targets. On some implementations, the properties of the default 321 window system provided framebuffer can change over time (e.g., in 322 response to window system events such as attaching the context to a 323 new window system drawable.) 324 325 Change the description of DeleteFramebuffers: 326 327 <framebuffers> contains <n> names of framebuffer objects to be 328 deleted. After a framebuffer object is deleted, it has no 329 attachments, and its name is again unused. If a framebuffer that is 330 currently bound to one or more of the targets DRAW_FRAMEBUFFER_NV or 331 READ_FRAMEBUFFER_NV is deleted, it is as though BindFramebuffer had 332 been executed with the corresponding <target> and <framebuffer> of 333 zero. Unused names in framebuffers are silently ignored, as is the 334 value zero. 335 336 The names bound to the draw and read framebuffer bindings can be 337 queried by calling GetIntegerv with the symbolic constants 338 DRAW_FRAMEBUFFER_BINDING and READ_FRAMEBUFFER_BINDING, respectively. 339 FRAMEBUFFER_BINDING is equivalent to DRAW_FRAMEBUFFER_BINDING 340 341 In section 4.4.3, modify the first two sentences of the 342 description of FramebufferRenderbuffer as follows: 343 344 "The <target> must be DRAW_FRAMEBUFFER_NV, READ_FRAMEBUFFER_NV, or 345 FRAMEBUFFER. If <target> is FRAMEBUFFER, it behaves as 346 though DRAW_FRAMEBUFFER_NV was specified. INVALID_OPERATION is 347 generated if the value of the corresponding binding is zero." 348 349 In section 4.4.3, modify the first two sentences of the 350 description of FramebufferTexture2D as follows: 351 352 "The <target> must be DRAW_FRAMEBUFFER_NV, READ_FRAMEBUFFER_NV, 353 or FRAMEBUFFER_NV. If <target> is FRAMEBUFFER, it behaves as 354 though DRAW_FRAMEBUFFER_NV was specified. INVALID_OPERATION is 355 generated if the value of the corresponding binding is zero." 356 357 In section 4.4.5, modify the first two paragraphs describing 358 CheckFramebufferStatus as follows: 359 360 "If <target> is not DRAW_FRAMEBUFFER_NV, READ_FRAMEBUFFER_NV or 361 FRAMEBUFFER, INVALID_ENUM is generated. FRAMEBUFFER is equivalent to 362 DRAW_FRAMEBUFFER_NV." 363 364 The values of SAMPLE_BUFFERS and SAMPLES are derived from the 365 attachments of the currently bound framebuffer object. If the 366 current DRAW_FRAMEBUFFER_BINDING is not framebuffer complete, then 367 both SAMPLE_BUFFERS and SAMPLES are undefined. Otherwise, SAMPLES is 368 equal to the value of RENDERBUFFER_SAMPLES for the attached images 369 (which all must have the same value for RENDERBUFFER_SAMPLES). 370 Further, SAMPLE_BUFFERS is one if SAMPLES is non-zero. Otherwise, 371 SAMPLE_BUFFERS is zero." 372 373Additions to Chapter 6 of the OpenGL ES 2.0.25 Specification (State and 374State Requests) 375 376 In section 6.1.3, modify the first sentence of the description of 377 GetFramebufferAttachmentParameteriv as follows: 378 379 "<target> must be DRAW_FRAMEBUFFER_NV, READ_FRAMEBUFFER_NV or 380 FRAMEBUFFER. FRAMEBUFFER is equivalent to DRAW_FRAMEBUFFER_NV." 381 382Dependencies on OpenGL ES 3.0 and later 383 384 If OpenGL ES 3.0 or later is supported, the described modifications to 385 language for BlitFramebufferNV also apply to BlitFramebuffer. 386 387 (Add to the end of the section describing BlitFramebuffer) 388 389 "If SAMPLE_BUFFERS for both the read and draw framebuffers are 390 greater than zero, and the values of SAMPLES for the read and draw 391 framebuffers are identical, the samples are copied without 392 modification from the read framebuffer to the draw framebuffer. 393 Otherwise, no copy is performed and an INVALID_OPERATION error is 394 generated. Note that the samples in the draw buffer are not 395 guaranteed to be at the same sample location as the read buffer, 396 so rendering using this newly created buffer can potentially 397 have geometry cracks or incorrect antialiasing. This may occur 398 if the sizes of the framebuffers do not match, if the 399 formats differ, or if the source and destination rectangles are 400 not defined with the same (X0,Y0) and (X1,Y1) bounds. 401 402 If SAMPLE_BUFFERS for either the read framebuffer or 403 draw framebuffer is greater than zero, no copy is performed and an 404 INVALID_OPERATION error is generated if the dimensions of the source 405 and destination rectangles provided to BlitFramebuffer are not 406 identical, or if the formats of the read and draw framebuffers are 407 not identical." 408 409 (In the error list for BlitFramebuffer, modify the item "An 410 INVALID_OPERATION error is generated if the draw framebuffer is 411 multisampled.") 412 413 * An INVALID_OPERATION error is generated if both the read and 414 draw buffers are multisampled, and SAMPLE_BUFFERS for the read and 415 draw buffers are not identical. 416 417 (In the error list for BlitFramebuffer, modify the item "An 418 INVALID_OPERATION error is generated if the read framebuffer is 419 multisampled, and the source and destination rectangles are not defined 420 with the same (X0, Y0) and (X1, Y1) bounds.") 421 422 * An INVALID_OPERATION error is generated if either the read or draw 423 buffer is multisampled, and the dimensions of the source and 424 destination rectangles are not identical, or if the formats of the 425 read and draw framebuffers are not identical. 426 427Dependencies on EXT_sRGB: 428 429 If EXT_sRGB is not supported, remove any language referring to 430 sRGB conversion during a BlitFramebufferNV operation. 431 432Dependencies on EXT_color_buffer_half_float: 433 434 If EXT_color_buffer_half_float is not supported, remove any language 435 referring to floating point conversion during a BlitFramebufferNV operation. 436 437Dependencies on EXT_discard_framebuffer: 438 439 If EXT_discard_framebuffer is supported, in Section 4.5 replace 440 the sentence: 441 442 "<target> must be FRAMEBUFFER." 443 444 with 445 446 "<target> must be DRAW_FRAMEBUFFER_NV, READ_FRAMEBUFFER_NV, or 447 FRAMEBUFFER. FRAMEBUFFER is equivalent to DRAW_FRAMEBUFFER_NV." 448 449 and relax the error to match. 450 451Dependencies on NV_fbo_color_attachments: 452 453 If NV_fbo_color_attachments is not supported, replace the sentence: 454 455 "There are the values of MAX_COLOR_ATTACHMENTS_NV color attachment 456 points, plus one set each for the depth and stencil attachment points." 457 458 with 459 460 "There is one color attachment point, plus one each for the depth 461 and stencil attachment points." 462 463Dependencies on NV_framebuffer_multisample: 464 465 If NV_framebuffer_multisample is not supported, ignore edits to the 466 second paragraph describing CheckFramebufferStatus. 467 468Dependencies on NV_read_buffer: 469 470 If NV_read_buffer is not supported, ignore any language referring to 471 ReadBufferNV. In this case the default OpenGL ES 2.0 behavior will 472 take place, where GL_COLOR_ATTACHMENT0 will implicitly always be the 473 read color buffer for application-created framebuffers and BACK for 474 the default framebuffer. 475 476Dependencies on NV_draw_buffers: 477 478 The absence of the NV_draw_buffers extension implies that there can be 479 ever only one destination color buffer. No replication of the one 480 read buffer data into possibly multiple destination color buffers can 481 happen. 482 483Errors 484 485 The error INVALID_FRAMEBUFFER_OPERATION is generated if 486 BlitFramebufferNV is called while the draw framebuffer is not framebuffer 487 complete. 488 489 The error INVALID_FRAMEBUFFER_OPERATION is generated if 490 BlitFramebufferNV, ReadPixels, CopyTex{Sub}Image2D, is called while the 491 read framebuffer is not framebuffer complete. 492 493 The error INVALID_VALUE is generated by BlitFramebufferNV if 494 <mask> has any bits set other than those named by 495 COLOR_BUFFER_BIT, DEPTH_BUFFER_BIT or STENCIL_BUFFER_BIT. 496 497 The error INVALID_OPERATION is generated if BlitFramebufferNV is 498 called and <mask> includes DEPTH_BUFFER_BIT or STENCIL_BUFFER_BIT 499 and <filter> is not NEAREST. 500 501 The error INVALID_OPERATION is generated if BlitFramebufferNV is 502 called and <mask> includes DEPTH_BUFFER_BIT or STENCIL_BUFFER_BIT 503 and the source and destination depth or stencil buffer formats do 504 not match. 505 506 The error INVALID_ENUM is generated by BlitFramebufferNV if 507 <filter> is not LINEAR or NEAREST. 508 509 The error INVALID_ENUM is generated if BindFramebuffer, 510 CheckFramebufferStatus, FramebufferTexture2D, 511 FramebufferRenderbuffer, or 512 GetFramebufferAttachmentParameteriv is called and <target> is 513 not DRAW_FRAMEBUFFER_NV, READ_FRAMEBUFFER_NV or FRAMEBUFFER. 514 515New State 516 517 (modify table 6.24, "Framebuffer State") 518 519 Get Value Type Get Command Initial Value Description Section 520 ---------------------------- ---- ----------- -------------- ------------------- ------------ 521 DRAW_FRAMEBUFFER_BINDING_NV Z+ GetIntegerv 0 framebuffer object bound 4.4.1 522 to DRAW_FRAMEBUFFER_NV 523 READ_FRAMEBUFFER_BINDING_NV Z+ GetIntegerv 0 framebuffer object 4.4.1 524 to READ_FRAMEBUFFER_NV 525 526 Remove reference to FRAMEBUFFER_BINDING. 527 528 529 530Issues 531 532 1) How does the functionality described by this extension differ 533 from that provided by EXT_framebuffer_blit? 534 - allow depth/stencil blits to be stretched using nearest filtering 535 - allow fixed point<-->floating point format conversion 536 - sRGB conversion 537 538 2) How does the functionality described by this extension differ 539 from that provided by ES 3.0? 540 - allow relocating MSAA resolve blits 541 - allow MSAA buffers as destination of blits 542 - allow overlapping blits with undefined results 543 544 3) How does this extension interact with NV_coverage_sample? 545 UNRESOLVED: 546 - should we allow blitting coverage information (GL_COVERAGE_BUFFER_BIT)? 547 - should we allow VCAA resolve blits? 548 - how to differentiate blitting the coverage buffer itself and doing a 549 resolve blit? 550 a) if read FBO has coverage buffer attachment, but draw FBO has not, 551 a VCAA resolve blit is being attempted 552 b) if GL_COVERAGE_BUFFER_BIT is part of <mask>, the coverage buffer 553 should be copied as-is. 554 - some surface blits would make it necessary to rotate the 555 coverage information itself. Better not allow copies of the coverage 556 buffer at all, restricting the VCAA functionality to resolve blits only? 557 558 559Revision History 560 #06 03 Mar 2015 Xi Chen 561 Add interaction with OpenGL ES 3.0 and later. 562 #05 02 Feb 2015 James Helferty 563 Add interaction with DiscardFramebuffer. 564 #04 31 Jan 2013 Greg Roth 565 Rewrote section 4.4.1 to better jibe with ES2.0 566 #03 09 Jan 2013 Greg Roth 567 Language clarifications and more formatting corrections. 568 #02 19 Apr 2012 Mathias Heyer 569 Clarifications and formatting corrections 570 #01 18 Apr 2012 Mathias Heyer 571 Initial draft. 572 573