1Name 2 3 APPLE_object_purgeable 4 5Name Strings 6 7 GL_APPLE_object_purgeable 8 9Contributors 10 11 Andrew Barnes 12 Bob Beretta 13 Kenneth Dyke 14 Alex Eddy 15 John Harper 16 Charlie Lao 17 Jeremy Sandmel 18 19Contact 20 21 Charlie Lao, Apple Computer Inc. (clao 'at' apple.com) 22 23Status 24 25 TBD 26 27Version 28 29 Last Modified Date: September 29, 2006 30 31Number 32 33 371 34 35Dependencies 36 37 OpenGL 1.5 is required. 38 39 The extension is written against the OpenGL 1.5 Specification. 40 41Overview 42 43 This extension provides the ability to mark the storage of OpenGL 44 objects as "purgeable". 45 46 Many of today's modern virtual memory systems include the concept of 47 purgeability in order to avoid unnecessary paging when the object 48 contents are no longer needed. In OpenGL, objects such as textures, 49 vertex buffers, pixel buffers, and renderbuffers all have 50 significant storage requirements. By default, the OpenGL is 51 required to preserve the contents of these objects regardless of 52 system resource stress, such as vram shortage or physical memory 53 shortage. Often this is accomplished by temporarily paging the 54 contents of objects that are not currently needed to some kind of 55 secondary storage area. This paging operation can be an unnecessary 56 computational expense in the cases where the data is not going to be 57 used again or where the content can be reproduced by the application 58 with less expense than the paging operation would require. 59 60 This extension defines a mechanism for the application to mark the 61 storage of OpenGL objects as "purgeable" in order to influence these 62 paging operations. The application can further control the 63 semantics of making object storage "purgeable" with two options 64 ("volatile" and "released") and "unpurgeable" with two options 65 ("undefined" and "retained") 66 67 Applications that use this extension will typically follow one of 68 two operational models. The typical model for most applications is 69 to mark an object storage as "purgeable" with the "volatile" option, 70 and then later mark the storage as "unpurgeable" with the "retained" 71 option. When this happens, the application may or may not need to 72 respecify the object contents, depending on the whether the object 73 storage was actually released. The application can find out whether 74 the storage was released by examining the return value of the 75 function which marks the storage as "unpurgeable". This model is 76 useful when the application does not know at the time it marks the 77 object storage as "purgeable" whether it will later need those 78 contents to be valid. 79 80 Another operational model is for an application to mark the storage 81 for an object as "purgeable" with the "released" option, and then 82 later mark the object "unpurgeable" with the "undefined" option. In 83 this latter model, the application intends to unconditionally reload 84 the object contents later on, and so it tells the GL that it is okay 85 if the contents are "undefined" when the storage is re-allocated. 86 87 Note that in both models, it is possible for the contents to become 88 undefined since they could have actually been purged from the system 89 in either case. The various options are still useful, however, 90 since they give more information to the GL about what the 91 application expects to happen and the GL can use this information to 92 make better predictions about which paging choices will be more 93 efficient. 94 95IP Status 96 97 No known IP claims. 98 99Issues 100 101 1. Why use two functions rather than just one? 102 103 The reason we chose two functions is that switching between the 104 two possible object states - purgeable and unpurgeable - might 105 be expensive. In addition, the return values of the operation 106 may be different depending on what state the object storage is 107 in and whether it has been purged or not. Therefore, we want to 108 enforce that the state is changed in matching pairs of function 109 calls, similar to Begin/End. In order to enforce this behavior, 110 we require two functions. 111 112 Applications are required to call ObjectPurgeable and 113 ObjectUnpurgeable in matched pairs, otherwise INVALID_OPERATION 114 is generated. 115 116 2. What does calling ObjectUnpurgeable with <option> set to 117 UNDEFINED_APPLE really mean? 118 119 An application calls ObjectUnpurgeable in order to change the 120 state of the object storage to unpurgeable. This is the 121 "default" state for object storage as defined traditionally in 122 GL. 123 124 Further, by using the <option> of UNDEFINED_APPLE, the 125 application is also indicating that it does not care about the 126 previous contents of the storage, if they still exist. This 127 gives the GL the freedom to allocate new storage or simply reuse 128 the old storage without spending time to figure out whether the 129 storage was actually freed and without having to tell the 130 application which choice was made. In addition, this allows the 131 function to return without blocking. 132 133 In contrast, calling ObjectUnpurgeable with <option> set to 134 RETAINED_APPLE requests the GL actually determine whether or not 135 it is possible to retain the original contents of the object, 136 and to restore the object storage to the previous contents, if 137 they still exist. This operation generally requires a flush of 138 the current command stream and often involveds additional work 139 to determine the state of object. 140 141 3. What's the difference between calling ObjectPurgeable and calling 142 DeleteTextures? 143 144 Calling ObjectPurgeable allows the GL to release all storage 145 that the GL has allocated for the object's contents, but will 146 still retain the object name and other non-content related state 147 of the object. If the application intends to re-use the object 148 again later, it will indicate so calling ObjectUnpurgeable. 149 150 In contrast, DeleteTextures deletes the object storage, the 151 object name, and the rest of the object state. The object can 152 never again be used. 153 154 Note that this means to set the object's name as unused and to 155 delete non-content related state of the object, the application 156 is still responsible for calling DeleteTextures. 157 158 There are some additional subtle differences though. 159 160 In general, calling ObjectPurgeable with the <option> 161 VOLATILE_APPLE requires less work of the GL than calling 162 ObjectPurgeable with the <option> set to RELEASED_APPLE. 163 Further, calling ObjectPurgeable with either option generally 164 requires less work of the GL than DeleteTextures. 165 166 Applications are encouraged, therefore, to use ObjectPurgeable 167 with the <option> set to VOLATILE_APPLE where possible and fall 168 back to ObjectPurgeable with the <option> set to RELEASED_APPLE 169 only if they prefer to have the GL do some amount of work to try 170 to release the storage. Only if the application really requires 171 the deletion of the object itself, should the application use 172 DeleteTextures. 173 174 Finally note, though the discussion above refers to 175 DeleteTextures, the same semantics apply to all object types 176 with Delete* operations, such as DeleteBuffers, 177 DeleteRenderbuffers, etc. that support this extension. 178 179 4. What should happen when ObjectPurgeable or ObjectUnpurgeable is 180 called between Begin/End? 181 182 This is illegal and returns INVALID_OPERATION error. 183 184 5. What should happen if ObjectPurgeable or ObjectUnpurgeable is 185 called on a currently bound texture, whether it is bound to the 186 current context or another context? 187 188 If the current context marks the storage of a currently bound 189 object as "purgeable", then attempts to read from or write to 190 the contents of that storage will result in undefined behavior. 191 192 Considering the multiple context case, we use the precedent of 193 all other state changes made by one context to an object bound 194 by another context. Namely, changes made to an object by 195 context A or only guaranteed to be "visible" to context B the 196 next time context B binds that object. In the interim period 197 the results of the state change are undefined. 198 199 For this extension, this means if context A marks an object's 200 storage as purgeable and that object is also bound by context B, 201 then it is undefined as to whether the object's storage will 202 have defined contents when used by context B. Note that in the 203 case of this particular extension, the whole point is to allow 204 the contents of the storage to become undefined so this is not a 205 particularly surprising outcome. 206 207 Applications are therefore advised to assume that they can not 208 rely on validity of the contents of any object whose storage has 209 been marked purgeable by any other context. Further, until some 210 context has marked the object storage as "unpurgeable" again and 211 the current context has re-bound the object, the current context 212 should not assume the contents are valid either. And even then 213 the contents should be assumed to be valid if and only if the 214 contents have been respecified or ObjectUnpurgeable returned the 215 value RETAINED_APPLE. 216 217 6. What should happen if the TestObject routine from the APPLE_fence 218 extension is called on an object whose storage has been marked 219 purgeable? 220 221 In short, it should operate "normally". 222 223 To be specific, if TestObject is called after calling 224 ObjectPurgeable with <option> set to VOLATILE_APPLE, the GL will 225 still determine if there are any pending operations using the 226 object, and TestObject will return TRUE or FALSE depending on 227 what it finds. 228 229 If TestObject is called after calling ObjectPurgeable with 230 <option> set to RELEASED_APPLE, the TestObject will generally 231 immediately return TRUE even though the object may still be in 232 use. This is acceptable since from user's point of view, the 233 object's storage has been freed from further use by the GL. 234 235 7. How does APPLE_object_purgeable interact with the 236 APPLE_texture_range extension? 237 238 First note that depending on the value of the storage hint 239 provided in the APPLE_texture_range extension, the GL may have 240 made multiple copies of the texture data. 241 242 In general, calling ObjectPurgeable with <option> set to 243 VOLATILE_APPLE option indicates that the GL should mark the 244 multiple copies of the storage as candidates for eviction but 245 should only release them as needed. In contrast, using the 246 <option> RELEASED_APPLE indicates that GL should try to go ahead 247 and release the storage for as many of these copies as is 248 efficient. 249 250 8. How does APPLE_object_purgeable interact with the 251 APPLE_client_storage extension? 252 253 For reference, APPLE_client_storage allows the application to 254 indicate that it will be responsible for allocating and 255 retaining the storage for a texture object. 256 257 In the APPLE_object_purgeable extension it is up to the 258 implementation to determine what happens when an object's 259 storage is marked purgeable and its up to the application to 260 query to determine whether the storage has been released. Given 261 that, the APPLE_client_storage has no real practical 262 interactions with APPLE_object_purgeable. 263 264 However, if APPLE_client_storage is supported on a platform that 265 gives the application control over the volatility of of client 266 memory, for instance via some sort of virtual memory system 267 call, then it's possible the application use the 268 platform-specific virtual memory API to mark as volatile the the 269 memory backing a texture using APPLE_client_storage for its 270 storage. The application on such a platform would be 271 responsible for using additional virtual memory system calls to 272 determine what happened to memory that was marked purgeable when 273 it goes to access that memory later on. In this scenario, the 274 effect would be very similar to the results of using the 275 APPLE_object_purgeable to mark a texture object's storage as 276 purgeable, but there is no direct interaction between the two 277 API's. 278 279 9. How does APPLE_object_purgeable interact with the 280 aglSurfaceTexture API? 281 282 For reference, the aglSurfaceTexture allows the application to 283 specify an AGL drawable as the storage for a GL texture object. 284 Such a texture object is informally called a "surface texture". 285 286 Similar to the APPLE_client_storage case, it is up to the API 287 that allocated the storage object to handle the purgeability of 288 that object. Given that, the APPLE_client_storage has no real 289 practical interactions with AGL surface textures. 290 291 292 10. How does APPLE_object_purgeable interact with the 293 ARB_vertex_buffer_object and ARB_pixel_buffer_object extensions? 294 295 The interactions should be analogous to those that occur with 296 texture objects. 297 298 To mark the storage for a buffer object as purgeable or 299 unpurgeable, the application can specify BUFFER_OBJECT_APPLE as 300 the <objectType> parameter in ObjectPurgeable or 301 ObjectUnpurgeable, respectively. The same rules about undefined 302 results from reading from or writing to the buffer object 303 storage while PURGEABLE_APPLE is TRUE apply as well. 304 305 13. After an object's storage has been marked as purgeable, what 306 should happen if CopyTexImage{1|2}D, CopyTexSubImage{1|2}D, 307 TexSubImage{1|2|3}D, or TexImage{1|2|3}D is called on the 308 texture? What if user try to texture from it or render to it? 309 310 After an object's storage has been marked purgeable, any usage 311 of the object is undefined until it is marked unpurgeable. 312 313 314New Procedures and Functions 315 316 enum ObjectPurgeableAPPLE(enum objectType, uint name, enum option) 317 enum ObjectUnpurgeableAPPLE(enum objectType, uint name, enum option) 318 void GetObjectParameterivAPPLE(enum objectType, uint name, enum 319 pname, int* params) 320 321New Types 322 323 None 324 325New Tokens 326 327 Accepted by the <option> parameter of ObjectPurgeable, and returned 328 by ObjectPurgeable: 329 330 RELEASED_APPLE 0x8A19 331 VOLATILE_APPLE 0x8A1A 332 333 Accepted by the <option> parameters of ObjectUnpurgeable, and 334 returned by ObjectUnpurgeable: 335 336 RETAINED_APPLE 0x8A1B 337 UNDEFINED_APPLE 0x8A1C 338 339 Accepted by the <pname> parameters of GetObjectParameteriv: 340 341 PURGEABLE_APPLE 0x8A1D 342 343 Accepted by the <objectType> parameters of ObjectPurgeableAPPLE, 344 ObjectUnpurgeableAPPLE and GetObjectParameteriv: 345 346 BUFFER_OBJECT_APPLE 0x85B3 347 348 (Note: BUFFER_OBJECT_APPLE is also defined in APPLE_fence extension 349 with the same value.) 350 351Additions to Chapter 2 of the OpenGL 1.5 Specification 352(OpenGL Operation) 353 354 None 355 356Additions to Chapter 3 of the OpenGL 1.5 Specification (Rasterization) 357 358 Additions to Chapter 3 of OpenGL 1.5 Specification (Rasterization) 359 360 (add a new section 3.8.16) 361 362 3.8.16 Purgeability 363 364 The internal data storage of a texture object, renderbuffer object, 365 or buffer object has a boolean state, PURGEABLE_APPLE that 366 influences how the object's storage is managed by the GL. The 367 initial value of PURGEABLE_APPLE is FALSE. The application can 368 change the value of PURGEABLE_APPLE by using the routines below. 369 370 The routine 371 372 enum ObjectPurgeableAPPLE(enum objectType, uint name, enum option) 373 374 sets PURGEABLE_APPLE to TRUE for the object of type <objectType> 375 with the id <name>. <objectType> must be one of TEXTURE, 376 BUFFER_OBJECT_APPLE, or RENDERBUFFER_EXT. If ObjectPurgeableAPPLE is 377 called and PURGEABLE_APPLE is already TRUE, the error 378 INVALID_OPERATION is generated. 379 380 While PURGEABLE_APPLE is TRUE, the GL may release the storage for 381 this object and the results of issuing any commands that read from 382 or write to the storage of that object are undefined. 383 384 <option> must be either VOLATILE_APPLE or RELEASED_APPLE. Calling 385 ObjectPurgeableAPPLE with either option sets PURGEABLE_APPLE to 386 TRUE, but the value of <option> is used by the GL as a hint to 387 indicate the application's intended future use of the named object's 388 storage. 389 390 By calling ObjectPurgeableAPPLE with an <option> of VOLATILE_APPLE, 391 the application is indicating that it does not know if it will want 392 to re-use the current contents of the object storage again later. 393 Further, the application is stating that it would like the GL to do 394 only the minimal amount of work required to set PURGEABLE_APPLE to 395 TRUE. If ObjectPurgeableAPPLE is called with an <option> of 396 VOLATILE_APPLE, then ObjectPurgeableAPPLE will also return the value 397 VOLATILE_APPLE. 398 399 In contrast, by calling ObjectPurgeableAPPLE with an <option> of 400 RELEASED_APPLE, the application is indicating that it does not 401 intend to re-use the contents of the storage again. Further, the 402 application is stating that it is acceptable for the GL to do a more 403 work to encourage the GL to actually release the storage for the 404 object. The actual mechanism for releasing the storage is 405 implementation-dependent, but it may require some level of 406 synchronization and may flush the current context. If 407 ObjectPurgeableAPPLE is called with an <option> of RELEASED_APPLE, 408 then ObjectPurgeableAPPLE may return either the value RELEASED_APPLE 409 or the value VOLATILE_APPLE. 410 411 If ObjectPurgeableAPPLE returns the value VOLATILE_APPLE, this means 412 that the storage for the object may not have been released when 413 ObjectPurgeableAPPLE returns. In contrast, if ObjectPurgeableAPPLE 414 returns the value RELEASED_APPLE, this means that the storage for 415 the object has been released when ObjectPurgeableAPPLE returns. 416 417 The routine 418 419 enum ObjectUnpurgeableAPPLE(enum object, uint name, enum option) 420 421 sets the value of PURGEABLE_APPLE to FALSE for the object of type 422 <objectType> with the id <name>. If ObjectUnpurgeableAPPLE is 423 called and PURGEABLE_APPLE is already FALSE, the error 424 INVALID_OPERATION is returned. 425 426 While PURGEABLE_APPLE is FALSE, the storage for an object will not 427 be released by the GL. This is the default state for object storage. 428 429 <option> must be either RETAINED_APPLE or UNDEFINED_APPLE. Calling 430 ObjectUnpurgeableAPPLE with either option sets PURGEABLE_APPLE to 431 FALSE, but the value of <option> is used by the GL as a hint to 432 indicate the application's intended future use of the named object's 433 storage. 434 435 By calling ObjectUnpurgeableAPPLE with an <option> of 436 RETAINED_APPLE, the application is indicating that it would like to 437 re-use the contents of the storage, if the storage has not yet been 438 released. Further, the application is stating that it is acceptable 439 for the GL to do more work to try to restore the storage the same 440 state it was in before PURGEABLE_APPLE was set to TRUE. The actual 441 mechanism for attempting to restore the storage of the object is 442 implementation-dependent, but it may require some level of 443 synchronization and may flush the current context. If 444 ObjectUnpurgeableAPPLE is called with an <option> of RETAINED_APPLE, 445 then ObjectPurgeableAPPLE may return either the value RETAINED_APPLE 446 or the value UNDEFINED_APPLE. 447 448 In contrast, by calling ObjectUnpurgeableAPPLE with an <option> of 449 UNDEFINED_APPLE, the application is indicating that it intends to 450 recreate the contents of the storage from scratch. Further, the 451 application is is stating that it would like the GL to do only the 452 minimal amount of work set PURGEABLE_APPLE to FALSE. If 453 ObjectUnpurgeableAPPLE is called with the <option> set to 454 UNDEFINED_APPLE, then ObjectUnpurgeableAPPLE will return the value 455 UNDEFINED_APPLE. 456 457 If ObjectUnpurgeableAPPLE returns the value UNDEFINED_APPLE, the 458 storage is in the same state as a newly created object with 459 undefined contents. In contrast, if ObjectUnpurgeableAPPLE returns 460 the value RETAINED_APPLE, this means that the storage has the same 461 the same contents it did when PURGEABLE_APPLE was most recently set 462 to FALSE. 463 464 465Additions to Chapter 4 of the OpenGL 1.5 Specification (Per-Fragment 466Operations and the Frame Buffer) 467 468 None 469 470Additions to Chapter 5 of the OpenGL 1.5 Specification 471(Special Functions) 472 473 None 474 475Additions to Chapter 6 of the OpenGL 1.5 Specification (State and State 476Requests) 477 478 (In section 6.1.3, Enumerated Queries, in the list of state query 479 functions, add the following) 480 481 "void GetObjectParameterivAPPLE(enum objectType, 482 int name, 483 enum pname, 484 void* params);" 485 486 (and add the following description to the end of this section) 487 488 "GetObjectParameterivAPPLE places in <params> information about the 489 object of type <objectType> with the id <name>. <objectType> must 490 be one of TEXTURE, BUFFER_OBJECT_APPLE, or RENDERBUFFER_EXT. 491 <name> must be a non-zero name of an object of type <type>. If 492 <pname> is PURGEABLE_APPLE, then when GetObjectParameterivAPPLE 493 returns, <params> will contain the current value of PURGEABLE_APPLE 494 for the named object's storage. Note that this query does not 495 return whether or not the object storage has been purged but simply 496 whether the state PURGEABLE_APPLE is set to TRUE or FALSE." 497 498Additions to Appendix A of the OpenGL 1.5 Specification (Invariance) 499 500 None 501 502Additions to the AGL/EGL/GLX/WGL Specifications 503 504 None 505 506Errors 507 508 INVALID_ENUM is generated if the <objectType> parameter of 509 ObjectPurgeableAPPLE or ObjectUnpurgeableAPPLE is not one of 510 TEXTURE, BUFFER_OBJECT_APPLE, RENDERBUFFER_EXT. 511 512 INVALID_ENUM is generated if the <option> parameter of 513 ObjectPurgeableAPPLE is not VOLATILE_APPLE or RELEASED_APPLE. 514 515 INVALID_ENUM is generated if the <option> parameter of 516 ObjectUnpurgeableAPPLE is not RETAINED_APPLE or UNDEFINED_APPLE. 517 518 INVALID_VALUE is generated if the <name> parameter of 519 ObjectUnpurgeableAPPLE or ObjectUnpurgeableAPPLE is zero. 520 521 INVALID_OPERATION is generated if either ObjectUnpurgeableAPPLE or 522 ObjectUnpurgeableAPPLE is called between the execution of Begin and 523 the corresponding execution of End. 524 525 INVALID_OPERATION is generated if ObjectPurgeableAPPLE is called on 526 an object with a current value of PURGEABLE set to TRUE 527 528 INVALID_OPERATION is generated if ObjectUnpurgeableAPPLE is called 529 on an object with a current value of PURGEABLE set to FALSE 530 531 INVALID_ENUM is generated if the <objectType> parameter of 532 GetObjectParameterivAPPLE is not one of TEXTURE, 533 BUFFER_OBJECT_APPLE, or RENDERBUFFER_EXT. 534 535 INVALID_VALUE is generated if the <name> parameter of 536 GetObjectParameterivAPPLE is not the name of an existing 537 object of type <objectType>. 538 539 INVALID_VALUE is generated if the <name> parameter of 540 GetObjectParameterivAPPLE is zero. 541 542 INVALID_ENUM is generated if the <pname> parameter of 543 GetObjectParameterivAPPLE is PURGEABLE_APPLE. 544 545 546New State 547 548 Each object type that supports this extension has the following new 549state: 550 551 Type Get Command Inital Value Description Section Attribute 552 ---- ----------------- ------------ ------------ ------- --------- 553 Z2 GetObjectParameter FALSE GL_PURGEABLE_APPLE 3.8.16 - 554 555New Implementation Dependent State 556 557 None 558 559Sample Code 560 561 A "one shot" texture is a texture specified, used once, and then 562 respecified again before it's next use. The sample code below shows 563 how to use APPLE_object_purgeable to handle "one shot" textures: 564 565 /* First, find out if the texture is purgeable already */ 566 boolean purgeable = FALSE; 567 GetObjectParameter(TEXTURE, name, &purgeable); 568 if(purgeable) 569 ObjectUnpurgeable(TEXTURE, name, UNDEFINED_APPLE); 570 571 /* Now that the texture is unpurgeable, respecify its contents 572 */ 573 BindTexture(TEXTURE_2D, name); 574 Enable(TEXTURE_2D); 575 TexImage2D(TEXTURE_2D, 0, RGBA, width, height, 0, RGBA, 576 UNSIGNED_BYTE, pixels); 577 578 /* Draw using the texture */ 579 MyDrawRoutine goes here(...); 580 581 /* Now mark the texture as purgeable */ 582 ObjectPurgeable(TEXTURE, name, RELEASED_APPLE); 583 584 Texture speculative caching: A FBO is created and texture_name is 585 attached to it. The application then renders to texture and is 586 expecting to use this texture later on. In the mean time it does 587 not want the GL to page it off because it is easy to recreate if 588 needed. 589 590 /* during system idle time, bind the fbo and render into it */ 591 BindFramebufferEXT(FRAMEBUFFER_EXT, fbo_name); 592 MyDrawRoutineToSpecifyTextureContents(...); 593 594 /* We've rendered into the texture but we don't necessarily */ 595 /* need for it to remain valid if the GL wants to release it */ 596 /* so we mark it as purgeable */ 597 ObjectPurgeable(TEXTURE, texture_name, VOLATILE_APPLE); 598 599 /* now do some other unrelated rendering */ 600 MyOtherDrawRoutineGoesHere(...); 601 602 /* Some time passes and then the application wants to */ 603 /* use the texture, so it markes the texture storage as */ 604 /* unpurgeable and indicates it would like the GL to try to */ 605 /* retain the storage if it still exists */ 606 607 obj_state = ObjectUnpurgeable(TEXTURE, 608 texture_name, RETAINED_APPLE); 609 if(obj_state == RETAINED_APPLE) 610 { 611 /* object storage was retained so we can go ahead and use it 612 */ 613 BindTexture(TEXTURE_2D, texture_name); 614 MyDrawRoutineThatUsesTheOriginalTexture(...); 615 } 616 else /* object storage was lost */ 617 { 618 /* We must recreate the original texture contents */ 619 BindFramebufferEXT(FRAMEBUFFER_EXT, fbo_name); 620 MyDrawRoutineToRespecifyTextureContents(...); 621 622 /* object storage has been re-specified so we can go */ 623 /* ahead and use it now */ 624 BindFramebufferEXT(FRAMEBUFFER_EXT, 0); 625 BindTexture(TEXTURE_2D, texture_name); 626 MyDrawRoutineThatUsesTheOriginalTexture(...); 627 } 628 629Revision History 630 631 Revision 2, 2006/10/20 632 - updated issue language to remove some stale resolutions 633 - revised and clarified language in terms of application intent 634 for the various <option> flags instead of implementation details 635 - replaced IsPurgeable with GetObjectParameter 636 - renamed extension "APPLE_object_purgeable" instead of 637 "APPLE_object_purgeability" to correlate with new state variable 638 GL_PURGEABLE_APPLE. 639 640 Revision 1, 2006/09/29 641 - Initial checkin. 642 643 644 645