Commit 4a48d9a3 by Ian Ewell

Initial implementation of ANGLE_stream_producer_d3d_texture_nv12.

Add the validation and entrypoints for ANGLE_stream_producer_d3d_texture_nv12, which is a new EGL extension currently being written. The purpose of this extension is to allow insertion of D3D11 NV12 textures to be inserted into a stream. This acts as the producer of the EGL stream. BUG=angleproject:1332 Change-Id: I50d4565cc82b63f7da7632adad4ac4c77d8800f2 Reviewed-on: https://chromium-review.googlesource.com/336695Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarShannon Woods <shannonwoods@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Commit-Queue: Ian Ewell <ewell@google.com>
parent 06feb81c
Name
ANGLE_stream_producer_d3d_texture_nv12
Name Strings
EGL_ANGLE_stream_producer_d3d_texture_nv12
Contributors
Ian Ewell
Geoff Lang
John Bauman
Contacts
Geoff Lang, Google (geofflang ‘at’ google.com)
Status
Draft
Version
Version 1, April 6, 2016
Number
EGL Extension #XXX
Dependencies
Requires EGL 1.5.
Requires OpenGL ES 2.0.
Requires the EGL_KHR_stream extension.
Requires the EGL_NV_stream_consumer_gltexture_yuv extension.
Requires the EGL_ANGLE_device_d3d extension.
Overview
This extension allows D3D11 NV12 textures to be inserted into an EGL stream
with the expectation that the stream consumer will be a YUV GL texture
consumer using a two plane configuration (i.e. a Y plane and a UV plane).
This will act as the producer of the stream.
New procedures and functions
EGLBoolean eglCreateStreamProducerD3DTextureNV12ANGLE
(EGLDisplay dpy,
EGLStreamKHR stream,
const EGLAttrib *attrib_list)
EGLBoolean eglStreamPostD3DTextureNV12ANGLE(EGLDisplay dpy,
EGLStreamKHR stream,
void *texture,
const EGLAttrib *attrib_list)
New Tokens
Accepted as an <attribute> in eglStreamPostD3DTextureNV12ANGLE:
EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE 0x3AAB
Replace section "3.10.3.1 No way to connect producer to EGLStream" in the
EGL_KHR_stream extension with this:
3.10.3.1 Stream Surface Producer
Call
EGLBoolean eglCreateStreamProducerD3DTextureNV12ANGLE(
EGLDisplay dpy,
EGLStreamKHR stream,
const EGLAttrib *attrib_list)
to create a producer that accepts D3D11 NV12 textures and connect it as the
producer of <stream>. <attrib_list> is used to specify attributes for the
stream producer. Currently there are no attributes to specify, and the
attribute list is used as a placeholder for future additions.
On failure, eglCreateStreamProducerD3DTextureNV12ANGLE returns EGL_FALSE and
generates an error.
- EGL_BAD_STATE_KHR is generated if <stream> is not in the state
EGL_STREAM_STATE_CONNECTING_KHR.
- EGL_BAD_MATCH is generated if <stream> does not have a connected GL
texture YUV consumer that is configured to bind to two OpenGL
textures: one for the Y plane and one for the UV plane.
- EGL_BAD_STREAM_KHR is generated if <stream> is not a valid EGLStream
generated for <dpy>.
- EGL_BAD_DISPLAY is generated if <dpy> is not a valid, initialized
display.
Add a section preceding "3.9.3 Posting Semantics" in the EGL specification:
3.9.x Posting to a Stream
To post a D3D11 NV12 texture to a stream, call
EGLBoolean eglStreamPostD3DTextureNV12ANGLE(
EGLDisplay dpy,
EGLStreamKHR stream,
void *texture,
const EGLAttrib *attrib_list);
If <stream> is an appropriately configured stream and <texture> points to a
valid ID3D11Texture2D object of the format DXGI_FORMAT_NV12 that is owned
by the same ID3D11Device that is queried with the EGL_ANGLE_device_d3d
extension, the texture will be posted to the stream and can be bound as one
or more OpenGL texture objects.
The parameter <attrib_list> allows for per-frame attributes to be specified
along with the texture. The only parameter currently available is
EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE, which allows the subresource id of
the texture that will be used to be specified. If this attribute is not
explicitly specified, it will default to the value of 0.
It is the responsibility of the application to perform any synchronization
between the insertion of the frame into the stream and the use of the
consumer textures output by the stream. The EGL_CONSUMER_LATENCY_USEC_KHR
attribute will have no effect on the function of the implementation of this
extension, but can still be used for communication between components of
the application.
The implementation will hold a reference to the D3D11 texture object if the
insertion is successful and will release the texture object when a new frame
is inserted or when the stream is destroyed.
On failure, eglStreamInsertD3DTextureNV12 returns EGL_FALSE and generates an
error.
- EGL_BAD_STATE is generated if <stream> is not in the state
EGL_STREAM_STATE_EMPTY_KHR, EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR,
or EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR.
- EGL_BAD_MATCH is generated if the stream is not associated with a
D3D11 NV12 texture producer.
- EGL_BAD_PARAMETER is generated if <texture> is not owned by the
queried device, is not in the format DXGI_FORMAT_NV12, is not
compatible with the implementation, or if the specified value for
EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE is not a valid subresource id for
the texture.
- EGL_BAD_STREAM_KHR is generated if <stream> is not a valid EGLStream.
- EGL_BAD_ATTRIBUTE is generated if an attribute other than
EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE is specified in <attrib_list>.
Revision History
#1 (April 6, 2016) Ian Ewell
- initial draft
\ No newline at end of file
......@@ -556,6 +556,17 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu
#define EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE 0x33AA
#endif /* EGL_ANGLE_experimental_present_path */
#ifndef EGL_ANGLE_stream_producer_d3d_texture_nv12
#define EGL_ANGLE_stream_producer_d3d_texture_nv12
#define EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE 0x3AAB
typedef EGLBoolean(EGLAPIENTRYP PFNEGLCREATESTREAMPRODUCERD3DTEXTURENV12ANGLEPROC)(EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
typedef EGLBoolean(EGLAPIENTRYP PFNEGLSTREAMPOSTD3DTEXTURENV12ANGLEPROC)(EGLDisplay dpy, EGLStreamKHR stream, void *texture, const EGLAttrib *attrib_list);
#ifdef EGL_EXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglCreateStreamProducerD3DTextureNV12ANGLE(EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglStreamPostD3DTextureNV12ANGLE(EGLDisplay dpy, EGLStreamKHR stream, void *texture, const EGLAttrib *attrib_list);
#endif
#endif /* EGL_ANGLE_stream_producer_d3d_texture_nv12 */
#ifndef EGL_ARM_pixmap_multisample_discard
#define EGL_ARM_pixmap_multisample_discard 1
#define EGL_DISCARD_SAMPLES_ARM 0x3286
......
......@@ -29,6 +29,11 @@ EGLAttrib AttributeMap::get(EGLAttrib key, EGLAttrib defaultValue) const
return (mAttributes.find(key) != mAttributes.end()) ? iter->second : defaultValue;
}
bool AttributeMap::isEmpty() const
{
return mAttributes.empty();
}
AttributeMap::const_iterator AttributeMap::begin() const
{
return mAttributes.begin();
......
......@@ -23,6 +23,7 @@ class AttributeMap final
void insert(EGLAttrib key, EGLAttrib value);
bool contains(EGLAttrib key) const;
EGLAttrib get(EGLAttrib key, EGLAttrib defaultValue) const;
bool isEmpty() const;
typedef std::map<EGLAttrib, EGLAttrib>::const_iterator const_iterator;
......
......@@ -640,7 +640,8 @@ DisplayExtensions::DisplayExtensions()
createContextNoError(false),
stream(false),
streamConsumerGLTexture(false),
streamConsumerGLTextureYUV(false)
streamConsumerGLTextureYUV(false),
streamProducerD3DTextureNV12(false)
{
}
......
......@@ -494,6 +494,9 @@ struct DisplayExtensions
// EGL_NV_stream_consumer_gltexture_yuv
bool streamConsumerGLTextureYUV;
// EGL_ANGLE_stream_producer_d3d_texture_nv12
bool streamProducerD3DTextureNV12;
};
struct DeviceExtensions
......
......@@ -1453,4 +1453,83 @@ Error ValidateStreamConsumerGLTextureExternalAttribsNV(const Display *display,
return Error(EGL_SUCCESS);
}
Error ValidateCreateStreamProducerD3DTextureNV12ANGLE(const Display *display,
const Stream *stream,
const AttributeMap &attribs)
{
const DisplayExtensions &displayExtensions = display->getExtensions();
if (!displayExtensions.streamProducerD3DTextureNV12)
{
return Error(EGL_BAD_ACCESS, "Stream producer extension not active");
}
Error error = ValidateStream(display, stream);
if (error.isError())
{
return error;
}
if (!attribs.isEmpty())
{
return Error(EGL_BAD_ATTRIBUTE, "Invalid attribute");
}
if (stream->getState() != EGL_STREAM_STATE_CONNECTING_KHR)
{
return Error(EGL_BAD_STATE_KHR, "Stream not in connecting state");
}
return Error(EGL_SUCCESS);
}
Error ValidateStreamPostD3DTextureNV12ANGLE(const Display *display,
const Stream *stream,
const void *texture,
const AttributeMap &attribs)
{
const DisplayExtensions &displayExtensions = display->getExtensions();
if (!displayExtensions.streamProducerD3DTextureNV12)
{
return Error(EGL_BAD_ACCESS, "Stream producer extension not active");
}
Error error = ValidateStream(display, stream);
if (error.isError())
{
return error;
}
for (auto &attributeIter : attribs)
{
EGLAttrib attribute = attributeIter.first;
EGLAttrib value = attributeIter.second;
switch (attribute)
{
case EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE:
if (value < 0)
{
return Error(EGL_BAD_PARAMETER, "Invalid subresource index");
}
break;
default:
return Error(EGL_BAD_ATTRIBUTE, "Invalid attribute");
}
}
if (stream->getState() != EGL_STREAM_STATE_EMPTY_KHR &&
stream->getState() != EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR &&
stream->getState() != EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR)
{
return Error(EGL_BAD_STATE_KHR, "Stream not fully configured");
}
if (texture == nullptr)
{
return Error(EGL_BAD_PARAMETER, "Texture must not be null");
}
return Error(EGL_SUCCESS);
}
}
......@@ -87,6 +87,13 @@ Error ValidateStreamConsumerGLTextureExternalAttribsNV(const Display *display,
gl::Context *context,
const Stream *stream,
const AttributeMap &attribs);
Error ValidateCreateStreamProducerD3DTextureNV12ANGLE(const Display *display,
const Stream *stream,
const AttributeMap &attribs);
Error ValidateStreamPostD3DTextureNV12ANGLE(const Display *display,
const Stream *stream,
const void *texture,
const AttributeMap &attribs);
// Other validation
Error ValidateCompatibleConfigs(const Display *display,
......
......@@ -343,4 +343,19 @@ EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalAttribsNV(EGLDisplay dp
{
return egl::StreamConsumerGLTextureExternalAttribsNV(dpy, stream, attrib_list);
}
EGLBoolean EGLAPIENTRY eglCreateStreamProducerD3DTextureNV12ANGLE(EGLDisplay dpy,
EGLStreamKHR stream,
const EGLAttrib *attrib_list)
{
return egl::CreateStreamProducerD3DTextureNV12ANGLE(dpy, stream, attrib_list);
}
EGLBoolean EGLAPIENTRY eglStreamPostD3DTextureNV12ANGLE(EGLDisplay dpy,
EGLStreamKHR stream,
void *texture,
const EGLAttrib *attrib_list)
{
return egl::StreamPostD3DTextureNV12ANGLE(dpy, stream, texture, attrib_list);
}
}
......@@ -55,6 +55,8 @@ EXPORTS
eglStreamConsumerAcquireKHR @61
eglStreamConsumerReleaseKHR @62
eglStreamConsumerGLTextureExternalAttribsNV @63
eglCreateStreamProducerD3DTextureNV12ANGLE @64
eglStreamPostD3DTextureNV12ANGLE @65
; 1.5 entry points
eglCreateSync @38
......
......@@ -785,4 +785,51 @@ EGLBoolean EGLAPIENTRY StreamConsumerGLTextureExternalAttribsNV(EGLDisplay dpy,
SetGlobalError(error);
return EGL_FALSE;
}
EGLBoolean EGLAPIENTRY CreateStreamProducerD3DTextureNV12ANGLE(EGLDisplay dpy,
EGLStreamKHR stream,
const EGLAttrib *attrib_list)
{
EVENT(
"(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR stream = 0x%0.8p, EGLAttrib attrib_list = 0x%0.8p",
dpy, stream, attrib_list);
Display *display = static_cast<Display *>(dpy);
Stream *streamObject = static_cast<Stream *>(stream);
AttributeMap attributes = AttributeMap::CreateFromAttribArray(attrib_list);
Error error =
ValidateCreateStreamProducerD3DTextureNV12ANGLE(display, streamObject, attributes);
if (error.isError())
{
SetGlobalError(error);
return EGL_FALSE;
}
SetGlobalError(error);
return EGL_FALSE;
}
EGLBoolean EGLAPIENTRY StreamPostD3DTextureNV12ANGLE(EGLDisplay dpy,
EGLStreamKHR stream,
void *texture,
const EGLAttrib *attrib_list)
{
EVENT(
"(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR stream = 0x%0.8p, void* texture = 0x%0.8p, "
"EGLAttrib attrib_list = 0x%0.8p",
dpy, stream, texture, attrib_list);
Display *display = static_cast<Display *>(dpy);
Stream *streamObject = static_cast<Stream *>(stream);
AttributeMap attributes = AttributeMap::CreateFromAttribArray(attrib_list);
Error error = ValidateStreamPostD3DTextureNV12ANGLE(display, streamObject, texture, attributes);
if (error.isError())
{
SetGlobalError(error);
return EGL_FALSE;
}
SetGlobalError(error);
return EGL_FALSE;
}
}
......@@ -69,6 +69,16 @@ ANGLE_EXPORT EGLBoolean EGLAPIENTRY
StreamConsumerGLTextureExternalAttribsNV(EGLDisplay dpy,
EGLStreamKHR stream,
const EGLAttrib *attrib_list);
}
// EGL_ANGLE_stream_producer_d3d_texture_nv12
ANGLE_EXPORT EGLBoolean EGLAPIENTRY
CreateStreamProducerD3DTextureNV12ANGLE(EGLDisplay dpy,
EGLStreamKHR stream,
const EGLAttrib *attrib_list);
ANGLE_EXPORT EGLBoolean EGLAPIENTRY StreamPostD3DTextureNV12ANGLE(EGLDisplay dpy,
EGLStreamKHR stream,
void *texture,
const EGLAttrib *attrib_list);
} // namespace egl
#endif // LIBGLESV2_ENTRYPOINTSEGLEXT_H_
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment