| Name |
| |
| APPLE_object_purgeable |
| |
| Name Strings |
| |
| GL_APPLE_object_purgeable |
| |
| Contributors |
| |
| Andrew Barnes |
| Bob Beretta |
| Kenneth Dyke |
| Alex Eddy |
| John Harper |
| Charlie Lao |
| Jeremy Sandmel |
| |
| Contact |
| |
| Charlie Lao, Apple Computer Inc. (clao 'at' apple.com) |
| |
| Status |
| |
| TBD |
| |
| Version |
| |
| Last Modified Date: September 29, 2006 |
| |
| Number |
| |
| 371 |
| |
| Dependencies |
| |
| OpenGL 1.5 is required. |
| |
| The extension is written against the OpenGL 1.5 Specification. |
| |
| Overview |
| |
| This extension provides the ability to mark the storage of OpenGL |
| objects as "purgeable". |
| |
| Many of today's modern virtual memory systems include the concept of |
| purgeability in order to avoid unnecessary paging when the object |
| contents are no longer needed. In OpenGL, objects such as textures, |
| vertex buffers, pixel buffers, and renderbuffers all have |
| significant storage requirements. By default, the OpenGL is |
| required to preserve the contents of these objects regardless of |
| system resource stress, such as vram shortage or physical memory |
| shortage. Often this is accomplished by temporarily paging the |
| contents of objects that are not currently needed to some kind of |
| secondary storage area. This paging operation can be an unnecessary |
| computational expense in the cases where the data is not going to be |
| used again or where the content can be reproduced by the application |
| with less expense than the paging operation would require. |
| |
| This extension defines a mechanism for the application to mark the |
| storage of OpenGL objects as "purgeable" in order to influence these |
| paging operations. The application can further control the |
| semantics of making object storage "purgeable" with two options |
| ("volatile" and "released") and "unpurgeable" with two options |
| ("undefined" and "retained") |
| |
| Applications that use this extension will typically follow one of |
| two operational models. The typical model for most applications is |
| to mark an object storage as "purgeable" with the "volatile" option, |
| and then later mark the storage as "unpurgeable" with the "retained" |
| option. When this happens, the application may or may not need to |
| respecify the object contents, depending on the whether the object |
| storage was actually released. The application can find out whether |
| the storage was released by examining the return value of the |
| function which marks the storage as "unpurgeable". This model is |
| useful when the application does not know at the time it marks the |
| object storage as "purgeable" whether it will later need those |
| contents to be valid. |
| |
| Another operational model is for an application to mark the storage |
| for an object as "purgeable" with the "released" option, and then |
| later mark the object "unpurgeable" with the "undefined" option. In |
| this latter model, the application intends to unconditionally reload |
| the object contents later on, and so it tells the GL that it is okay |
| if the contents are "undefined" when the storage is re-allocated. |
| |
| Note that in both models, it is possible for the contents to become |
| undefined since they could have actually been purged from the system |
| in either case. The various options are still useful, however, |
| since they give more information to the GL about what the |
| application expects to happen and the GL can use this information to |
| make better predictions about which paging choices will be more |
| efficient. |
| |
| IP Status |
| |
| No known IP claims. |
| |
| Issues |
| |
| 1. Why use two functions rather than just one? |
| |
| The reason we chose two functions is that switching between the |
| two possible object states - purgeable and unpurgeable - might |
| be expensive. In addition, the return values of the operation |
| may be different depending on what state the object storage is |
| in and whether it has been purged or not. Therefore, we want to |
| enforce that the state is changed in matching pairs of function |
| calls, similar to Begin/End. In order to enforce this behavior, |
| we require two functions. |
| |
| Applications are required to call ObjectPurgeable and |
| ObjectUnpurgeable in matched pairs, otherwise INVALID_OPERATION |
| is generated. |
| |
| 2. What does calling ObjectUnpurgeable with <option> set to |
| UNDEFINED_APPLE really mean? |
| |
| An application calls ObjectUnpurgeable in order to change the |
| state of the object storage to unpurgeable. This is the |
| "default" state for object storage as defined traditionally in |
| GL. |
| |
| Further, by using the <option> of UNDEFINED_APPLE, the |
| application is also indicating that it does not care about the |
| previous contents of the storage, if they still exist. This |
| gives the GL the freedom to allocate new storage or simply reuse |
| the old storage without spending time to figure out whether the |
| storage was actually freed and without having to tell the |
| application which choice was made. In addition, this allows the |
| function to return without blocking. |
| |
| In contrast, calling ObjectUnpurgeable with <option> set to |
| RETAINED_APPLE requests the GL actually determine whether or not |
| it is possible to retain the original contents of the object, |
| and to restore the object storage to the previous contents, if |
| they still exist. This operation generally requires a flush of |
| the current command stream and often involveds additional work |
| to determine the state of object. |
| |
| 3. What's the difference between calling ObjectPurgeable and calling |
| DeleteTextures? |
| |
| Calling ObjectPurgeable allows the GL to release all storage |
| that the GL has allocated for the object's contents, but will |
| still retain the object name and other non-content related state |
| of the object. If the application intends to re-use the object |
| again later, it will indicate so calling ObjectUnpurgeable. |
| |
| In contrast, DeleteTextures deletes the object storage, the |
| object name, and the rest of the object state. The object can |
| never again be used. |
| |
| Note that this means to set the object's name as unused and to |
| delete non-content related state of the object, the application |
| is still responsible for calling DeleteTextures. |
| |
| There are some additional subtle differences though. |
| |
| In general, calling ObjectPurgeable with the <option> |
| VOLATILE_APPLE requires less work of the GL than calling |
| ObjectPurgeable with the <option> set to RELEASED_APPLE. |
| Further, calling ObjectPurgeable with either option generally |
| requires less work of the GL than DeleteTextures. |
| |
| Applications are encouraged, therefore, to use ObjectPurgeable |
| with the <option> set to VOLATILE_APPLE where possible and fall |
| back to ObjectPurgeable with the <option> set to RELEASED_APPLE |
| only if they prefer to have the GL do some amount of work to try |
| to release the storage. Only if the application really requires |
| the deletion of the object itself, should the application use |
| DeleteTextures. |
| |
| Finally note, though the discussion above refers to |
| DeleteTextures, the same semantics apply to all object types |
| with Delete* operations, such as DeleteBuffers, |
| DeleteRenderbuffers, etc. that support this extension. |
| |
| 4. What should happen when ObjectPurgeable or ObjectUnpurgeable is |
| called between Begin/End? |
| |
| This is illegal and returns INVALID_OPERATION error. |
| |
| 5. What should happen if ObjectPurgeable or ObjectUnpurgeable is |
| called on a currently bound texture, whether it is bound to the |
| current context or another context? |
| |
| If the current context marks the storage of a currently bound |
| object as "purgeable", then attempts to read from or write to |
| the contents of that storage will result in undefined behavior. |
| |
| Considering the multiple context case, we use the precedent of |
| all other state changes made by one context to an object bound |
| by another context. Namely, changes made to an object by |
| context A or only guaranteed to be "visible" to context B the |
| next time context B binds that object. In the interim period |
| the results of the state change are undefined. |
| |
| For this extension, this means if context A marks an object's |
| storage as purgeable and that object is also bound by context B, |
| then it is undefined as to whether the object's storage will |
| have defined contents when used by context B. Note that in the |
| case of this particular extension, the whole point is to allow |
| the contents of the storage to become undefined so this is not a |
| particularly surprising outcome. |
| |
| Applications are therefore advised to assume that they can not |
| rely on validity of the contents of any object whose storage has |
| been marked purgeable by any other context. Further, until some |
| context has marked the object storage as "unpurgeable" again and |
| the current context has re-bound the object, the current context |
| should not assume the contents are valid either. And even then |
| the contents should be assumed to be valid if and only if the |
| contents have been respecified or ObjectUnpurgeable returned the |
| value RETAINED_APPLE. |
| |
| 6. What should happen if the TestObject routine from the APPLE_fence |
| extension is called on an object whose storage has been marked |
| purgeable? |
| |
| In short, it should operate "normally". |
| |
| To be specific, if TestObject is called after calling |
| ObjectPurgeable with <option> set to VOLATILE_APPLE, the GL will |
| still determine if there are any pending operations using the |
| object, and TestObject will return TRUE or FALSE depending on |
| what it finds. |
| |
| If TestObject is called after calling ObjectPurgeable with |
| <option> set to RELEASED_APPLE, the TestObject will generally |
| immediately return TRUE even though the object may still be in |
| use. This is acceptable since from user's point of view, the |
| object's storage has been freed from further use by the GL. |
| |
| 7. How does APPLE_object_purgeable interact with the |
| APPLE_texture_range extension? |
| |
| First note that depending on the value of the storage hint |
| provided in the APPLE_texture_range extension, the GL may have |
| made multiple copies of the texture data. |
| |
| In general, calling ObjectPurgeable with <option> set to |
| VOLATILE_APPLE option indicates that the GL should mark the |
| multiple copies of the storage as candidates for eviction but |
| should only release them as needed. In contrast, using the |
| <option> RELEASED_APPLE indicates that GL should try to go ahead |
| and release the storage for as many of these copies as is |
| efficient. |
| |
| 8. How does APPLE_object_purgeable interact with the |
| APPLE_client_storage extension? |
| |
| For reference, APPLE_client_storage allows the application to |
| indicate that it will be responsible for allocating and |
| retaining the storage for a texture object. |
| |
| In the APPLE_object_purgeable extension it is up to the |
| implementation to determine what happens when an object's |
| storage is marked purgeable and its up to the application to |
| query to determine whether the storage has been released. Given |
| that, the APPLE_client_storage has no real practical |
| interactions with APPLE_object_purgeable. |
| |
| However, if APPLE_client_storage is supported on a platform that |
| gives the application control over the volatility of of client |
| memory, for instance via some sort of virtual memory system |
| call, then it's possible the application use the |
| platform-specific virtual memory API to mark as volatile the the |
| memory backing a texture using APPLE_client_storage for its |
| storage. The application on such a platform would be |
| responsible for using additional virtual memory system calls to |
| determine what happened to memory that was marked purgeable when |
| it goes to access that memory later on. In this scenario, the |
| effect would be very similar to the results of using the |
| APPLE_object_purgeable to mark a texture object's storage as |
| purgeable, but there is no direct interaction between the two |
| API's. |
| |
| 9. How does APPLE_object_purgeable interact with the |
| aglSurfaceTexture API? |
| |
| For reference, the aglSurfaceTexture allows the application to |
| specify an AGL drawable as the storage for a GL texture object. |
| Such a texture object is informally called a "surface texture". |
| |
| Similar to the APPLE_client_storage case, it is up to the API |
| that allocated the storage object to handle the purgeability of |
| that object. Given that, the APPLE_client_storage has no real |
| practical interactions with AGL surface textures. |
| |
| |
| 10. How does APPLE_object_purgeable interact with the |
| ARB_vertex_buffer_object and ARB_pixel_buffer_object extensions? |
| |
| The interactions should be analogous to those that occur with |
| texture objects. |
| |
| To mark the storage for a buffer object as purgeable or |
| unpurgeable, the application can specify BUFFER_OBJECT_APPLE as |
| the <objectType> parameter in ObjectPurgeable or |
| ObjectUnpurgeable, respectively. The same rules about undefined |
| results from reading from or writing to the buffer object |
| storage while PURGEABLE_APPLE is TRUE apply as well. |
| |
| 13. After an object's storage has been marked as purgeable, what |
| should happen if CopyTexImage{1|2}D, CopyTexSubImage{1|2}D, |
| TexSubImage{1|2|3}D, or TexImage{1|2|3}D is called on the |
| texture? What if user try to texture from it or render to it? |
| |
| After an object's storage has been marked purgeable, any usage |
| of the object is undefined until it is marked unpurgeable. |
| |
| |
| New Procedures and Functions |
| |
| enum ObjectPurgeableAPPLE(enum objectType, uint name, enum option) |
| enum ObjectUnpurgeableAPPLE(enum objectType, uint name, enum option) |
| void GetObjectParameterivAPPLE(enum objectType, uint name, enum |
| pname, int* params) |
| |
| New Types |
| |
| None |
| |
| New Tokens |
| |
| Accepted by the <option> parameter of ObjectPurgeable, and returned |
| by ObjectPurgeable: |
| |
| RELEASED_APPLE 0x8A19 |
| VOLATILE_APPLE 0x8A1A |
| |
| Accepted by the <option> parameters of ObjectUnpurgeable, and |
| returned by ObjectUnpurgeable: |
| |
| RETAINED_APPLE 0x8A1B |
| UNDEFINED_APPLE 0x8A1C |
| |
| Accepted by the <pname> parameters of GetObjectParameteriv: |
| |
| PURGEABLE_APPLE 0x8A1D |
| |
| Accepted by the <objectType> parameters of ObjectPurgeableAPPLE, |
| ObjectUnpurgeableAPPLE and GetObjectParameteriv: |
| |
| BUFFER_OBJECT_APPLE 0x85B3 |
| |
| (Note: BUFFER_OBJECT_APPLE is also defined in APPLE_fence extension |
| with the same value.) |
| |
| Additions to Chapter 2 of the OpenGL 1.5 Specification |
| (OpenGL Operation) |
| |
| None |
| |
| Additions to Chapter 3 of the OpenGL 1.5 Specification (Rasterization) |
| |
| Additions to Chapter 3 of OpenGL 1.5 Specification (Rasterization) |
| |
| (add a new section 3.8.16) |
| |
| 3.8.16 Purgeability |
| |
| The internal data storage of a texture object, renderbuffer object, |
| or buffer object has a boolean state, PURGEABLE_APPLE that |
| influences how the object's storage is managed by the GL. The |
| initial value of PURGEABLE_APPLE is FALSE. The application can |
| change the value of PURGEABLE_APPLE by using the routines below. |
| |
| The routine |
| |
| enum ObjectPurgeableAPPLE(enum objectType, uint name, enum option) |
| |
| sets PURGEABLE_APPLE to TRUE for the object of type <objectType> |
| with the id <name>. <objectType> must be one of TEXTURE, |
| BUFFER_OBJECT_APPLE, or RENDERBUFFER_EXT. If ObjectPurgeableAPPLE is |
| called and PURGEABLE_APPLE is already TRUE, the error |
| INVALID_OPERATION is generated. |
| |
| While PURGEABLE_APPLE is TRUE, the GL may release the storage for |
| this object and the results of issuing any commands that read from |
| or write to the storage of that object are undefined. |
| |
| <option> must be either VOLATILE_APPLE or RELEASED_APPLE. Calling |
| ObjectPurgeableAPPLE with either option sets PURGEABLE_APPLE to |
| TRUE, but the value of <option> is used by the GL as a hint to |
| indicate the application's intended future use of the named object's |
| storage. |
| |
| By calling ObjectPurgeableAPPLE with an <option> of VOLATILE_APPLE, |
| the application is indicating that it does not know if it will want |
| to re-use the current contents of the object storage again later. |
| Further, the application is stating that it would like the GL to do |
| only the minimal amount of work required to set PURGEABLE_APPLE to |
| TRUE. If ObjectPurgeableAPPLE is called with an <option> of |
| VOLATILE_APPLE, then ObjectPurgeableAPPLE will also return the value |
| VOLATILE_APPLE. |
| |
| In contrast, by calling ObjectPurgeableAPPLE with an <option> of |
| RELEASED_APPLE, the application is indicating that it does not |
| intend to re-use the contents of the storage again. Further, the |
| application is stating that it is acceptable for the GL to do a more |
| work to encourage the GL to actually release the storage for the |
| object. The actual mechanism for releasing the storage is |
| implementation-dependent, but it may require some level of |
| synchronization and may flush the current context. If |
| ObjectPurgeableAPPLE is called with an <option> of RELEASED_APPLE, |
| then ObjectPurgeableAPPLE may return either the value RELEASED_APPLE |
| or the value VOLATILE_APPLE. |
| |
| If ObjectPurgeableAPPLE returns the value VOLATILE_APPLE, this means |
| that the storage for the object may not have been released when |
| ObjectPurgeableAPPLE returns. In contrast, if ObjectPurgeableAPPLE |
| returns the value RELEASED_APPLE, this means that the storage for |
| the object has been released when ObjectPurgeableAPPLE returns. |
| |
| The routine |
| |
| enum ObjectUnpurgeableAPPLE(enum object, uint name, enum option) |
| |
| sets the value of PURGEABLE_APPLE to FALSE for the object of type |
| <objectType> with the id <name>. If ObjectUnpurgeableAPPLE is |
| called and PURGEABLE_APPLE is already FALSE, the error |
| INVALID_OPERATION is returned. |
| |
| While PURGEABLE_APPLE is FALSE, the storage for an object will not |
| be released by the GL. This is the default state for object storage. |
| |
| <option> must be either RETAINED_APPLE or UNDEFINED_APPLE. Calling |
| ObjectUnpurgeableAPPLE with either option sets PURGEABLE_APPLE to |
| FALSE, but the value of <option> is used by the GL as a hint to |
| indicate the application's intended future use of the named object's |
| storage. |
| |
| By calling ObjectUnpurgeableAPPLE with an <option> of |
| RETAINED_APPLE, the application is indicating that it would like to |
| re-use the contents of the storage, if the storage has not yet been |
| released. Further, the application is stating that it is acceptable |
| for the GL to do more work to try to restore the storage the same |
| state it was in before PURGEABLE_APPLE was set to TRUE. The actual |
| mechanism for attempting to restore the storage of the object is |
| implementation-dependent, but it may require some level of |
| synchronization and may flush the current context. If |
| ObjectUnpurgeableAPPLE is called with an <option> of RETAINED_APPLE, |
| then ObjectPurgeableAPPLE may return either the value RETAINED_APPLE |
| or the value UNDEFINED_APPLE. |
| |
| In contrast, by calling ObjectUnpurgeableAPPLE with an <option> of |
| UNDEFINED_APPLE, the application is indicating that it intends to |
| recreate the contents of the storage from scratch. Further, the |
| application is is stating that it would like the GL to do only the |
| minimal amount of work set PURGEABLE_APPLE to FALSE. If |
| ObjectUnpurgeableAPPLE is called with the <option> set to |
| UNDEFINED_APPLE, then ObjectUnpurgeableAPPLE will return the value |
| UNDEFINED_APPLE. |
| |
| If ObjectUnpurgeableAPPLE returns the value UNDEFINED_APPLE, the |
| storage is in the same state as a newly created object with |
| undefined contents. In contrast, if ObjectUnpurgeableAPPLE returns |
| the value RETAINED_APPLE, this means that the storage has the same |
| the same contents it did when PURGEABLE_APPLE was most recently set |
| to FALSE. |
| |
| |
| Additions to Chapter 4 of the OpenGL 1.5 Specification (Per-Fragment |
| Operations and the Frame Buffer) |
| |
| None |
| |
| Additions to Chapter 5 of the OpenGL 1.5 Specification |
| (Special Functions) |
| |
| None |
| |
| Additions to Chapter 6 of the OpenGL 1.5 Specification (State and State |
| Requests) |
| |
| (In section 6.1.3, Enumerated Queries, in the list of state query |
| functions, add the following) |
| |
| "void GetObjectParameterivAPPLE(enum objectType, |
| int name, |
| enum pname, |
| void* params);" |
| |
| (and add the following description to the end of this section) |
| |
| "GetObjectParameterivAPPLE places in <params> information about the |
| object of type <objectType> with the id <name>. <objectType> must |
| be one of TEXTURE, BUFFER_OBJECT_APPLE, or RENDERBUFFER_EXT. |
| <name> must be a non-zero name of an object of type <type>. If |
| <pname> is PURGEABLE_APPLE, then when GetObjectParameterivAPPLE |
| returns, <params> will contain the current value of PURGEABLE_APPLE |
| for the named object's storage. Note that this query does not |
| return whether or not the object storage has been purged but simply |
| whether the state PURGEABLE_APPLE is set to TRUE or FALSE." |
| |
| Additions to Appendix A of the OpenGL 1.5 Specification (Invariance) |
| |
| None |
| |
| Additions to the AGL/EGL/GLX/WGL Specifications |
| |
| None |
| |
| Errors |
| |
| INVALID_ENUM is generated if the <objectType> parameter of |
| ObjectPurgeableAPPLE or ObjectUnpurgeableAPPLE is not one of |
| TEXTURE, BUFFER_OBJECT_APPLE, RENDERBUFFER_EXT. |
| |
| INVALID_ENUM is generated if the <option> parameter of |
| ObjectPurgeableAPPLE is not VOLATILE_APPLE or RELEASED_APPLE. |
| |
| INVALID_ENUM is generated if the <option> parameter of |
| ObjectUnpurgeableAPPLE is not RETAINED_APPLE or UNDEFINED_APPLE. |
| |
| INVALID_VALUE is generated if the <name> parameter of |
| ObjectUnpurgeableAPPLE or ObjectUnpurgeableAPPLE is zero. |
| |
| INVALID_OPERATION is generated if either ObjectUnpurgeableAPPLE or |
| ObjectUnpurgeableAPPLE is called between the execution of Begin and |
| the corresponding execution of End. |
| |
| INVALID_OPERATION is generated if ObjectPurgeableAPPLE is called on |
| an object with a current value of PURGEABLE set to TRUE |
| |
| INVALID_OPERATION is generated if ObjectUnpurgeableAPPLE is called |
| on an object with a current value of PURGEABLE set to FALSE |
| |
| INVALID_ENUM is generated if the <objectType> parameter of |
| GetObjectParameterivAPPLE is not one of TEXTURE, |
| BUFFER_OBJECT_APPLE, or RENDERBUFFER_EXT. |
| |
| INVALID_VALUE is generated if the <name> parameter of |
| GetObjectParameterivAPPLE is not the name of an existing |
| object of type <objectType>. |
| |
| INVALID_VALUE is generated if the <name> parameter of |
| GetObjectParameterivAPPLE is zero. |
| |
| INVALID_ENUM is generated if the <pname> parameter of |
| GetObjectParameterivAPPLE is PURGEABLE_APPLE. |
| |
| |
| New State |
| |
| Each object type that supports this extension has the following new |
| state: |
| |
| Type Get Command Inital Value Description Section Attribute |
| ---- ----------------- ------------ ------------ ------- --------- |
| Z2 GetObjectParameter FALSE GL_PURGEABLE_APPLE 3.8.16 - |
| |
| New Implementation Dependent State |
| |
| None |
| |
| Sample Code |
| |
| A "one shot" texture is a texture specified, used once, and then |
| respecified again before it's next use. The sample code below shows |
| how to use APPLE_object_purgeable to handle "one shot" textures: |
| |
| /* First, find out if the texture is purgeable already */ |
| boolean purgeable = FALSE; |
| GetObjectParameter(TEXTURE, name, &purgeable); |
| if(purgeable) |
| ObjectUnpurgeable(TEXTURE, name, UNDEFINED_APPLE); |
| |
| /* Now that the texture is unpurgeable, respecify its contents |
| */ |
| BindTexture(TEXTURE_2D, name); |
| Enable(TEXTURE_2D); |
| TexImage2D(TEXTURE_2D, 0, RGBA, width, height, 0, RGBA, |
| UNSIGNED_BYTE, pixels); |
| |
| /* Draw using the texture */ |
| MyDrawRoutine goes here(...); |
| |
| /* Now mark the texture as purgeable */ |
| ObjectPurgeable(TEXTURE, name, RELEASED_APPLE); |
| |
| Texture speculative caching: A FBO is created and texture_name is |
| attached to it. The application then renders to texture and is |
| expecting to use this texture later on. In the mean time it does |
| not want the GL to page it off because it is easy to recreate if |
| needed. |
| |
| /* during system idle time, bind the fbo and render into it */ |
| BindFramebufferEXT(FRAMEBUFFER_EXT, fbo_name); |
| MyDrawRoutineToSpecifyTextureContents(...); |
| |
| /* We've rendered into the texture but we don't necessarily */ |
| /* need for it to remain valid if the GL wants to release it */ |
| /* so we mark it as purgeable */ |
| ObjectPurgeable(TEXTURE, texture_name, VOLATILE_APPLE); |
| |
| /* now do some other unrelated rendering */ |
| MyOtherDrawRoutineGoesHere(...); |
| |
| /* Some time passes and then the application wants to */ |
| /* use the texture, so it markes the texture storage as */ |
| /* unpurgeable and indicates it would like the GL to try to */ |
| /* retain the storage if it still exists */ |
| |
| obj_state = ObjectUnpurgeable(TEXTURE, |
| texture_name, RETAINED_APPLE); |
| if(obj_state == RETAINED_APPLE) |
| { |
| /* object storage was retained so we can go ahead and use it |
| */ |
| BindTexture(TEXTURE_2D, texture_name); |
| MyDrawRoutineThatUsesTheOriginalTexture(...); |
| } |
| else /* object storage was lost */ |
| { |
| /* We must recreate the original texture contents */ |
| BindFramebufferEXT(FRAMEBUFFER_EXT, fbo_name); |
| MyDrawRoutineToRespecifyTextureContents(...); |
| |
| /* object storage has been re-specified so we can go */ |
| /* ahead and use it now */ |
| BindFramebufferEXT(FRAMEBUFFER_EXT, 0); |
| BindTexture(TEXTURE_2D, texture_name); |
| MyDrawRoutineThatUsesTheOriginalTexture(...); |
| } |
| |
| Revision History |
| |
| Revision 2, 2006/10/20 |
| - updated issue language to remove some stale resolutions |
| - revised and clarified language in terms of application intent |
| for the various <option> flags instead of implementation details |
| - replaced IsPurgeable with GetObjectParameter |
| - renamed extension "APPLE_object_purgeable" instead of |
| "APPLE_object_purgeability" to correlate with new state variable |
| GL_PURGEABLE_APPLE. |
| |
| Revision 1, 2006/09/29 |
| - Initial checkin. |
| |
| |
| |