| Name |
| |
| KHR_stream_consumer_gltexture |
| |
| Name Strings |
| |
| EGL_KHR_stream_consumer_gltexture |
| |
| Contributors |
| |
| Acorn Pooley |
| Jamie Gennis |
| Marcus Lorentzon |
| |
| Contacts |
| |
| Acorn Pooley, NVIDIA (apooley 'at' nvidia.com) |
| |
| Notice |
| |
| Copyright (c) 2011-2013 The Khronos Group Inc. Copyright terms at |
| http://www.khronos.org/registry/speccopyright.html |
| |
| Status |
| |
| Complete. |
| Approved by the Khronos Board of Promoters on December 2, 2011. |
| |
| Version |
| |
| Version 11, June 18, 2012 |
| |
| Number |
| |
| EGL Extension #33 |
| |
| Dependencies |
| |
| Requires EGL 1.2. |
| Requires OpenGL ES 1.1 or OpenGL ES 2.0. |
| |
| Requires the EGL_KHR_stream extension. |
| Requires the GL_NV_EGL_stream_consumer_external extension. |
| |
| Overview |
| |
| This extension allows an OpenGL(ES) texture to be connected to an |
| EGLStream as its consumer. Image frames from the EGLStream can be |
| 'latched' into the texture as the contents of the texture. This |
| is equivalent to copying the image into the texture, but on most |
| implementations a copy is not needed so this is faster. |
| |
| New Procedures and Functions |
| |
| EGLBoolean eglStreamConsumerGLTextureExternalKHR( |
| EGLDisplay dpy, |
| EGLStreamKHR stream) |
| |
| EGLBoolean eglStreamConsumerAcquireKHR( |
| EGLDisplay dpy, |
| EGLStreamKHR stream); |
| |
| EGLBoolean eglStreamConsumerReleaseKHR( |
| EGLDisplay dpy, |
| EGLStreamKHR stream); |
| |
| New Tokens |
| |
| Accepted as an attribute in the <attrib_list> parameter of |
| eglCreateStreamKHR and as the <attribute> parameter of |
| eglStreamAttribKHR and eglQueryStreamKHR |
| |
| EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR 0x321E |
| |
| Replace section "3.10.2.1 No way to connect consumer to EGLStream" in |
| the EGL_KHR_stream extension with this: |
| |
| 3.10.2.1 GL Texture External consumer |
| |
| Call |
| |
| EGLBoolean eglStreamConsumerGLTextureExternalKHR( |
| EGLDisplay dpy, |
| EGLStreamKHR stream) |
| |
| to connect the texture object currently bound to the active |
| texture unit's GL_TEXTURE_EXTERNAL_OES texture target in the |
| OpenGL or OpenGL ES context current to the calling thread as the |
| consumer of <stream>. |
| |
| (Note: Before this can succeed a GL_TEXTURE_EXTERNAL_OES texture |
| must be bound to the active texture unit of the GL context current |
| to the calling thread. To create a GL_TEXTURE_EXTERNAL_OES |
| texture and bind it to the current context, call glBindTexture() |
| with <target> set to GL_TEXTURE_EXTERNAL_OES and <texture> set to |
| the name of the GL_TEXTURE_EXTERNAL_OES (which may or may not have |
| previously been created). This is described in the |
| GL_NV_EGL_stream_consumer_external extension.) |
| |
| On failure EGL_FALSE is returned and an error is generated. |
| |
| - EGL_BAD_STATE_KHR is generated if <stream> is not in state |
| EGL_STREAM_STATE_CREATED_KHR. |
| |
| - EGL_BAD_ACCESS is generated if there is no GL context |
| current to the calling thread. |
| |
| - EGL_BAD_ACCESS is generated unless a nonzero texture object |
| name is bound to the GL_TEXTURE_EXTERNAL_OES texture target |
| of the GL context current to the calling thread. |
| |
| - EGL_BAD_STREAM_KHR is generated if <stream> is not a valid |
| EGLStreamKHR created for <dpy>. |
| |
| - EGL_BAD_DISPLAY is generated if <dpy> is not a valid, |
| initialized EGLDisplay. |
| |
| |
| On success the texture is connected to the <stream>, <stream> is |
| placed in the EGL_STREAM_STATE_CONNECTING_KHR state, and EGL_TRUE is |
| returned. |
| |
| If the texture is later deleted, connected to a different |
| EGLStream, or connected to an EGLImage, then <stream> will be |
| placed into the EGL_STREAM_STATE_DISCONNECTED_KHR state. |
| |
| If the <stream> is later destroyed then the texture will be |
| "incomplete" until it is connected to a new EGLStream, connected |
| to a new EGLImage, or deleted. |
| |
| |
| Call |
| |
| EGLBoolean eglStreamConsumerAcquireKHR( |
| EGLDisplay dpy, |
| EGLStreamKHR stream); |
| |
| to "latch" the most recent image frame from <stream> into the |
| texture that is the consumer of <stream>. The GLES context |
| containing the texture must be bound to the current thread. If |
| the GLES texture is also used in shared contexts current to other |
| threads then the texture must be re-bound in those contexts to |
| guarantee the new texture is used. |
| |
| eglStreamConsumerAcquireKHR will block until either the timeout |
| specified by EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR expires, or the |
| value of EGL_BAD_STATE_KHR is neither EGL_STREAM_STATE_EMPTY_KHR nor |
| EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR (whichever comes first). |
| |
| Blocking effectively waits until a new image frame (that has never |
| been consumed) is available in the EGLStream. By default the |
| timeout is zero and the function does not block. |
| |
| eglStreamConsumerAcquireKHR returns EGL_TRUE if an image frame was |
| successfully latched into the texture object. |
| |
| If the producer has not inserted any new image frames since the |
| last call to eglStreamConsumerAcquireKHR then |
| eglStreamConsumerAcquireKHR will "latch" the same image frame it |
| latched last time eglStreamConsumerAcquireKHR was called. If the |
| producer has inserted one new image frame since the last call to |
| eglStreamConsumerAcquireKHR then eglStreamConsumerAcquireKHR will |
| "latch" the newly inserted image frame. If the producer has |
| inserted more than one new image frame since the last call to |
| eglStreamConsumerAcquireKHR then all but the most recently |
| inserted image frames are discarded and the |
| eglStreamConsumerAcquireKHR will "latch" the most recently |
| inserted image frame. |
| |
| The application can use the value of EGL_CONSUMER_FRAME_KHR to |
| identify which image frame was actually latched. |
| |
| On failure the texture becomes "incomplete", eglStreamConsumerAcquireKHR |
| returns EGL_FALSE, and an error is generated. |
| |
| - EGL_BAD_STATE_KHR is generated if <stream> is not in state |
| EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR or |
| EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR. |
| |
| - EGL_BAD_ACCESS is generated if there is no GL context |
| current to the calling thread, or if the GL context current |
| to the calling thread does not contain a texture that is |
| connected as the consumer of the EGLStream. |
| |
| - EGL_BAD_STREAM_KHR is generated if <stream> is not a valid |
| EGLStream created for <dpy>. |
| |
| - EGL_BAD_DISPLAY is generated if <dpy> is not a valid, |
| initialized EGLDisplay. |
| |
| |
| After using the texture call |
| |
| EGLBoolean eglStreamConsumerReleaseKHR( |
| EGLDisplay dpy, |
| EGLStreamKHR stream); |
| |
| to release the image frame back to the stream. |
| eglStreamConsumerReleaseKHR() will prevent the EGLStream and |
| producer from re-using and/or modifying the image frame until all |
| preceding GL commands that use the image frame as a texture have |
| completed. If eglStreamConsumerAcquireKHR() is called twice on the |
| same EGLStream without an intervening call to |
| eglStreamConsumerReleaseKHR() then eglStreamConsumerReleaseKHR() is |
| implicitly called at the start of eglStreamConsumerAcquireKHR(). |
| |
| After successfully calling eglStreamConsumerReleaseKHR the texture |
| becomes "incomplete". |
| |
| If eglStreamConsumerReleaseKHR is called twice without a successful |
| intervening call to eglStreamConsumerAcquireKHR, or called with no |
| previous call to eglStreamConsumerAcquireKHR, then the call does |
| nothing and the texture remains in "incomplete" state. This is |
| not an error. |
| |
| If eglStreamConsumerReleaseKHR fails EGL_FALSE is returned and an error is |
| generated. |
| |
| - EGL_BAD_STATE_KHR is generated if <stream> is not in state |
| EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR or |
| EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR. |
| |
| - EGL_BAD_ACCESS is generated if there is no GL context |
| current to the calling thread, or if the GL context current |
| to the calling thread does not contain the texture to which |
| the EGLStream is connected. |
| |
| - EGL_BAD_STREAM_KHR is generated if <stream> is not a valid |
| EGLStream created for <dpy>. |
| |
| - EGL_BAD_DISPLAY is generated if <dpy> is not a valid, |
| initialized EGLDisplay. |
| |
| |
| The application should estimate the time that will elapse from the |
| time a new frame becomes available (i.e. the state becomes |
| EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR) and the time the frame |
| is presented to the user. The application should set this as the |
| value of the EGL_CONSUMER_LATENCY_USEC attribute by calling |
| eglStreamAttribKHR(). The value will depend on the complexity of |
| the scene being rendered and the platform that the app is running |
| on. It may be difficult to estimate except by experimentation on |
| a specific platform. The default value is implementation |
| dependent and may be a good enough estimate for some situations. |
| If the estimate changes over time the application may modify the |
| value of EGL_CONSUMER_LATENCY_USEC. |
| |
| If the EGLStream is deleted while an image frame is acquired (i.e. |
| after calling eglStreamConsumerAcquireKHR and before calling |
| eglStreamConsumerReleaseKHR) then the EGLStream resources will not |
| be freed until the acquired image frame is released. However it |
| is an error to call eglStreamConsumerReleaseKHR after deleting the |
| EGLStream because <stream> is no longer a valid handle. In this |
| situation the image can be released (and the EGLStream resources |
| freed) by doing any one of |
| - deleting the GL_TEXTURE_EXTERNAL (call glDeleteTextures) |
| - connecting the GL_TEXTURE_EXTERNAL to another EGLStream |
| (call eglStreamConsumerGLTextureExternalKHR) |
| - connecting the GL_TEXTURE_EXTERNAL to an EGLImage (if the |
| GL_OES_EGL_image_external extension is supported, call |
| glEGLImageTargetTexture2DOES) |
| |
| Add a new subsection 3.10.4.6 at the end of section "3.10.4 EGLStream |
| Attributes" in the EGL_KHR_stream extension spec: |
| |
| 3.10.4.6 EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR Attribute |
| |
| This attribute is read/write. The default value is 0. It |
| indicates the maximum amount of time (in microseconds) that |
| eglStreamConsumerAcquireKHR should block. If 0 (the default) it |
| will not block at all. If negative it will block indefinitely. |
| |
| Issues |
| 1. How to notify the app when a new image is available |
| - callback? |
| - pro: easy to use |
| - con: introduces extra threads into EGL which does not define such |
| behavior now - would have to define a lot of semantics (e.g. what |
| can you call from the callback?) |
| - EGL_KHR_reusable_sync signaled? |
| - this is how EGL_KHR_stream_consumer_endpoint does it |
| - pro: simpler to specify |
| - pro: easy to use if that is all you are waiting for |
| - con: difficult to wait on this AND other events simultaneously? |
| - blocking call to eglStreamConsumerAcquireKHR? |
| |
| RESOLVED: Use the EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR to make |
| eglStreamConsumerAcquireKHR blocking if desired. Additional |
| mechanisms can be added as layered extensions. |
| |
| 2. What to call this extension? |
| EGL_NV_stream_consumer_gltexture |
| EGL_EXT_stream_consumer_gltexture |
| EGL_KHR_stream_consumer_gltexture |
| EGL_KHR_stream_consumer_gltexture_external |
| |
| RESOLVED: EGL_KHR_stream_consumer_gltexture |
| |
| 3. Should it be possible to connect an EGLStream to this consumer |
| (texture), and then later reconnect the same stream to a different |
| consumer? |
| |
| RESOLVED: no |
| |
| There may be reasons to allow this later, but for the time being |
| there is no use for this. Adding this functionality can be |
| considered in the future with a layered extension. |
| |
| 4. Do we need both this extension and |
| GL_NV_EGL_stream_consumer_external? Should we just have one |
| extension that takes the place of both? If so should it be an |
| EGL or a GL extension? |
| |
| UNRESOLVED |
| |
| SUGGESTION: need both |
| |
| See issue 1 in GL_NV_EGL_stream_consumer_external.txt |
| |
| 5. What happens if the EGLStream is deleted while the consumer |
| has an image acquired? |
| |
| This case is a problem because after the EGLStream is deleted |
| the EGLStreamKHR handle is no longer valid, which means |
| eglStreamConsumerReleaseKHR cannot be called (because it would |
| return EGL_BAD_STREAM). |
| |
| Possible resolutions: |
| |
| A) Do not allow the EGLStream to be deleted while an image is |
| acquired. |
| |
| B) Allow the EGLStream to be deleted. Allow the EGLStreamKHR |
| handle to be used in a call to eglStreamConsumerReleaseKHR() |
| after it has been deleted. |
| |
| C) Allow the EGLStream to be deleted. It is an error to call |
| eglStreamConsumerReleaseKHR() after the stream is deleted. To |
| release the image the app must |
| - delete the GL_TEXTURE_EXTERNAL texture object |
| or - connect another EGLStream to the GL_TEXTURE_EXTERNAL |
| texture object |
| or - connect an EGLImage to the GL_TEXTURE_EXTERNAL |
| texture object |
| |
| D) Make the call to EGLStream implicitly call |
| eglStreamConsumerReleaseKHR if an image is acquired. This |
| requires the GL context is current to the thread that deletes |
| the EGLStream. |
| |
| E) Make the call to EGLStream implicitly call |
| eglStreamConsumerReleaseKHR if an image is acquired, and state |
| that this has to work even if the GL context is current to a |
| different thread or not current to any thread. |
| |
| Pros/cons: |
| - B violates EGL object handle lifetime policies |
| - E is hard/impossible to implement on some systems |
| - D makes deletion fail for complicated reasons |
| - A makes deletion fail for less complicated reasons |
| |
| RESOLVED: option C |
| |
| Revision History |
| |
| #11 (June 18. 2012) Acorn Pooley |
| - Replace EGLStream with EGLStreamKHR in function prototypes. |
| |
| #10 (October 12, 2011) Acorn Pooley |
| - Fix confusing error in eglStreamConsumerAcquireKHR description. |
| |
| #9 (October 4, 2011) Acorn Pooley |
| - Convert from an NV extension to a KHR extension |
| |
| #8 (September 30, 2011) Acorn Pooley |
| - Add issue 5 and clarify EGLStream deletion while image is |
| acquired. |
| |
| #7 (September 27, 2011) Acorn Pooley |
| - Assign enum values (bug 8064) |
| |
| #6 (Aug 3, 2011) Acorn Pooley |
| - rename GL_OES_EGL_stream_external to |
| GL_NV_EGL_stream_consumer_external |
| |
| #5 (Aug 2, 2011) Acorn Pooley |
| - Add dependency on GL_OES_EGL_stream_external |
| |
| #4 (Aug 2, 2011) Acorn Pooley |
| - Fix spelling and grammar |
| |
| #3 (July 6, 2011) Acorn Pooley |
| - Rename EGL_KHR_image_stream to EGL_KHR_stream |
| |
| #2 (June 29, 2011) Acorn Pooley |
| - change how texture is connected to stream to match |
| EGL_KHR_stream spec. |
| - Add EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_NV |
| |
| #1 (April 20, 2011) Acorn Pooley |
| - initial draft |
| # vim:ai:ts=4:sts=4:expandtab:textwidth=70 |