Commit 2018c0ba by Geoff Lang Committed by Commit Bot

Add a EGL_ANGLE_d3d_texture_client_buffer extension.

Allows creation of pbuffers from D3D texture objects. BUG=540829 BUG=angleproject:1144 Change-Id: If8ea717ef011608cd01357c217837133d726d3ea Reviewed-on: https://chromium-review.googlesource.com/316804 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 9f4583dd
Name
ANGLE_d3d_texture_client_buffer
Name Strings
EGL_ANGLE_d3d_texture_client_buffer
Contributors
Geoff Lang
Contacts
Geoff Lang, Google Inc. (geofflang 'at' google.com)
Status
Draft
Version
Version 1, Oct 5, 2016
Number
EGL Extension #??
Dependencies
This extension is written against the wording of the EGL 1.4
Specification.
References the EGL_ANGLE_device_d3d extension.
Overview
This extension allows creating EGL surfaces from D3D texture objects.
New Types
None
New Procedures and Functions
None
New Tokens
Accepted in the <buftype> parameter of eglCreatePbufferFromClientBuffer:
EGL_D3D_TEXTURE_ANGLE 0x33A3
Additions to Chapter 3 of the EGL 1.4 Specification (EGL Functions and Errors)
Replace the last sentence of paragraph 1 of Section 3.5.3 with the
following text.
"Currently, the only client API resources which may be bound in this
fashion are OpenVG VGImage objects and Direct3D texture objects."
Replace the last sentence of paragraph 2 ("To bind a client API...") of
Section 3.5.3 with the following text.
"When <buftype> is EGL_OPENVG_IMAGE or EGL_D3D_TEXTURE_ANGLE, the width and
height of the pbuffer are determined by the width and height of <buffer>."
Replace the third paragraph of Section 3.5.3 with the following text.
"<buftype> specifies the type of buffer to be bound. The only allowed values
of <buftype> are EGL_OPENVG_IMAGE and EGL_D3D_TEXTURE_ANGLE".
Append the following text to the fourth paragraph of Section 3.5.3.
"When <buftype> is EGL_D3D_TEXTURE_ANGLE, <buffer> must be
a valid D3D texture object, cast into the type EGLClientBuffer. See table
egl.restrictions for acceptable texture object types and formats. If the
EGL_ANGLE_device_d3d extension is present, the provided D3D texture object
must have been created by the same D3D device queried from the display.
If these requirements are not met, an EGL_BAD_PARAMETER error is
generated."
---------------------------------------------------------------------------
Resource Type Resource Restrictions
---------------------------------------------------------------------------
IDirect3DTexture9 Memory pool must be D3DPOOL_DEFAULT. Format must be
D3DFMT_R8G8B8, D3DFMT_A8R8G8B8, D3DFMT_A16B16G16R16F or
D3DFMT_A32B32G32R32F.
ID3D11Texture2D Usage flags must be D3D11_USAGE_DEFAULT. Format must be
DXGI_FORMAT_R8G8B8A8_UNORM,
DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
DXGI_FORMAT_B8G8R8A8_UNORM,
DXGI_FORMAT_B8G8R8A8_UNORM_SRGB,
DXGI_FORMAT_R16G16B16A16_FLOAT or
DXGI_FORMAT_R32G32B32A32_FLOAT.
--------------------------------------------------------------------------
Table egl.restrictions - Restrictions on D3D resources that can be used
as a <buffer>.
--------------------------------------------------------------------------
Append to the end of Section 3.5.3.
"When a pbuffer is created with type EGL_D3D_TEXTURE_ANGLE, the contents
of the associcated D3D texture object are undefined while the pbuffer is
the current read surface, draw surface or bound to a client texture."
Issues
Revision History
Version 1, 2016/10/05 - first draft.
...@@ -472,6 +472,11 @@ EGLAPI EGLint EGLAPIENTRY eglDupNativeFenceFDANDROID (EGLDisplay dpy, EGLSyncKHR ...@@ -472,6 +472,11 @@ EGLAPI EGLint EGLAPIENTRY eglDupNativeFenceFDANDROID (EGLDisplay dpy, EGLSyncKHR
#define EGL_DXGI_KEYED_MUTEX_ANGLE 0x33A2 #define EGL_DXGI_KEYED_MUTEX_ANGLE 0x33A2
#endif /* EGL_ANGLE_keyed_mutex */ #endif /* EGL_ANGLE_keyed_mutex */
#ifndef EGL_ANGLE_d3d_texture_client_buffer
#define EGL_ANGLE_d3d_texture_client_buffer 1
#define EGL_D3D_TEXTURE_ANGLE 0x33A3
#endif /* EGL_ANGLE_d3d_texture_client_buffer */
#ifndef EGL_ANGLE_query_surface_pointer #ifndef EGL_ANGLE_query_surface_pointer
#define EGL_ANGLE_query_surface_pointer 1 #define EGL_ANGLE_query_surface_pointer 1
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value); typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
......
...@@ -762,6 +762,7 @@ Caps::Caps() ...@@ -762,6 +762,7 @@ Caps::Caps()
DisplayExtensions::DisplayExtensions() DisplayExtensions::DisplayExtensions()
: createContextRobustness(false), : createContextRobustness(false),
d3dShareHandleClientBuffer(false), d3dShareHandleClientBuffer(false),
d3dTextureClientBuffer(false),
surfaceD3DTexture2DShareHandle(false), surfaceD3DTexture2DShareHandle(false),
querySurfacePointer(false), querySurfacePointer(false),
windowFixedSize(false), windowFixedSize(false),
...@@ -800,6 +801,7 @@ std::vector<std::string> DisplayExtensions::getStrings() const ...@@ -800,6 +801,7 @@ std::vector<std::string> DisplayExtensions::getStrings() const
// | Extension name | Supported flag | Output vector | // | Extension name | Supported flag | Output vector |
InsertExtensionString("EGL_EXT_create_context_robustness", createContextRobustness, &extensionStrings); InsertExtensionString("EGL_EXT_create_context_robustness", createContextRobustness, &extensionStrings);
InsertExtensionString("EGL_ANGLE_d3d_share_handle_client_buffer", d3dShareHandleClientBuffer, &extensionStrings); InsertExtensionString("EGL_ANGLE_d3d_share_handle_client_buffer", d3dShareHandleClientBuffer, &extensionStrings);
InsertExtensionString("EGL_ANGLE_d3d_texture_client_buffer", d3dTextureClientBuffer, &extensionStrings);
InsertExtensionString("EGL_ANGLE_surface_d3d_texture_2d_share_handle", surfaceD3DTexture2DShareHandle, &extensionStrings); InsertExtensionString("EGL_ANGLE_surface_d3d_texture_2d_share_handle", surfaceD3DTexture2DShareHandle, &extensionStrings);
InsertExtensionString("EGL_ANGLE_query_surface_pointer", querySurfacePointer, &extensionStrings); InsertExtensionString("EGL_ANGLE_query_surface_pointer", querySurfacePointer, &extensionStrings);
InsertExtensionString("EGL_ANGLE_window_fixed_size", windowFixedSize, &extensionStrings); InsertExtensionString("EGL_ANGLE_window_fixed_size", windowFixedSize, &extensionStrings);
......
...@@ -533,6 +533,9 @@ struct DisplayExtensions ...@@ -533,6 +533,9 @@ struct DisplayExtensions
// EGL_ANGLE_d3d_share_handle_client_buffer // EGL_ANGLE_d3d_share_handle_client_buffer
bool d3dShareHandleClientBuffer; bool d3dShareHandleClientBuffer;
// EGL_ANGLE_d3d_texture_client_buffer
bool d3dTextureClientBuffer;
// EGL_ANGLE_surface_d3d_texture_2d_share_handle // EGL_ANGLE_surface_d3d_texture_2d_share_handle
bool surfaceD3DTexture2DShareHandle; bool surfaceD3DTexture2DShareHandle;
......
...@@ -587,8 +587,11 @@ Error Display::createPbufferSurface(const Config *configuration, const Attribute ...@@ -587,8 +587,11 @@ Error Display::createPbufferSurface(const Config *configuration, const Attribute
return egl::Error(EGL_SUCCESS); return egl::Error(EGL_SUCCESS);
} }
Error Display::createPbufferFromClientBuffer(const Config *configuration, EGLClientBuffer shareHandle, Error Display::createPbufferFromClientBuffer(const Config *configuration,
const AttributeMap &attribs, Surface **outSurface) EGLenum buftype,
EGLClientBuffer clientBuffer,
const AttributeMap &attribs,
Surface **outSurface)
{ {
ASSERT(isInitialized()); ASSERT(isInitialized());
...@@ -598,7 +601,7 @@ Error Display::createPbufferFromClientBuffer(const Config *configuration, EGLCli ...@@ -598,7 +601,7 @@ Error Display::createPbufferFromClientBuffer(const Config *configuration, EGLCli
} }
std::unique_ptr<Surface> surface( std::unique_ptr<Surface> surface(
new PbufferSurface(mImplementation, configuration, shareHandle, attribs)); new PbufferSurface(mImplementation, configuration, buftype, clientBuffer, attribs));
ANGLE_TRY(surface->initialize()); ANGLE_TRY(surface->initialize());
ASSERT(outSurface != nullptr); ASSERT(outSurface != nullptr);
...@@ -947,6 +950,14 @@ bool Display::isValidNativeWindow(EGLNativeWindowType window) const ...@@ -947,6 +950,14 @@ bool Display::isValidNativeWindow(EGLNativeWindowType window) const
return mImplementation->isValidNativeWindow(window); return mImplementation->isValidNativeWindow(window);
} }
Error Display::validateClientBuffer(const Config *configuration,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const AttributeMap &attribs)
{
return mImplementation->validateClientBuffer(configuration, buftype, clientBuffer, attribs);
}
bool Display::isValidDisplay(const egl::Display *display) bool Display::isValidDisplay(const egl::Display *display)
{ {
const ANGLEPlatformDisplayMap *anglePlatformDisplayMap = GetANGLEPlatformDisplayMap(); const ANGLEPlatformDisplayMap *anglePlatformDisplayMap = GetANGLEPlatformDisplayMap();
......
...@@ -57,7 +57,10 @@ class Display final : angle::NonCopyable ...@@ -57,7 +57,10 @@ class Display final : angle::NonCopyable
Error createWindowSurface(const Config *configuration, EGLNativeWindowType window, const AttributeMap &attribs, Error createWindowSurface(const Config *configuration, EGLNativeWindowType window, const AttributeMap &attribs,
Surface **outSurface); Surface **outSurface);
Error createPbufferSurface(const Config *configuration, const AttributeMap &attribs, Surface **outSurface); Error createPbufferSurface(const Config *configuration, const AttributeMap &attribs, Surface **outSurface);
Error createPbufferFromClientBuffer(const Config *configuration, EGLClientBuffer shareHandle, const AttributeMap &attribs, Error createPbufferFromClientBuffer(const Config *configuration,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const AttributeMap &attribs,
Surface **outSurface); Surface **outSurface);
Error createPixmapSurface(const Config *configuration, NativePixmapType nativePixmap, const AttributeMap &attribs, Error createPixmapSurface(const Config *configuration, NativePixmapType nativePixmap, const AttributeMap &attribs,
Surface **outSurface); Surface **outSurface);
...@@ -88,6 +91,11 @@ class Display final : angle::NonCopyable ...@@ -88,6 +91,11 @@ class Display final : angle::NonCopyable
bool isValidStream(const Stream *stream) const; bool isValidStream(const Stream *stream) const;
bool isValidNativeWindow(EGLNativeWindowType window) const; bool isValidNativeWindow(EGLNativeWindowType window) const;
Error validateClientBuffer(const Config *configuration,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const AttributeMap &attribs);
static bool isValidDisplay(const egl::Display *display); static bool isValidDisplay(const egl::Display *display);
static bool isValidNativeDisplay(EGLNativeDisplayType display); static bool isValidNativeDisplay(EGLNativeDisplayType display);
static bool hasExistingWindowSurface(EGLNativeWindowType window); static bool hasExistingWindowSurface(EGLNativeWindowType window);
......
...@@ -211,19 +211,23 @@ EGLint Surface::getHeight() const ...@@ -211,19 +211,23 @@ EGLint Surface::getHeight() const
Error Surface::bindTexImage(gl::Texture *texture, EGLint buffer) Error Surface::bindTexImage(gl::Texture *texture, EGLint buffer)
{ {
ASSERT(!mTexture.get()); ASSERT(!mTexture.get());
ANGLE_TRY(mImplementation->bindTexImage(texture, buffer));
texture->bindTexImageFromSurface(this); texture->bindTexImageFromSurface(this);
mTexture.set(texture); mTexture.set(texture);
return mImplementation->bindTexImage(texture, buffer);
return Error(EGL_SUCCESS);
} }
Error Surface::releaseTexImage(EGLint buffer) Error Surface::releaseTexImage(EGLint buffer)
{ {
ANGLE_TRY(mImplementation->releaseTexImage(buffer));
ASSERT(mTexture.get()); ASSERT(mTexture.get());
mTexture->releaseTexImageFromSurface(); mTexture->releaseTexImageFromSurface();
mTexture.set(nullptr); mTexture.set(nullptr);
return mImplementation->releaseTexImage(buffer); return Error(EGL_SUCCESS);
} }
Error Surface::getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) Error Surface::getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc)
...@@ -308,12 +312,13 @@ PbufferSurface::PbufferSurface(rx::EGLImplFactory *implFactory, ...@@ -308,12 +312,13 @@ PbufferSurface::PbufferSurface(rx::EGLImplFactory *implFactory,
PbufferSurface::PbufferSurface(rx::EGLImplFactory *implFactory, PbufferSurface::PbufferSurface(rx::EGLImplFactory *implFactory,
const Config *config, const Config *config,
EGLClientBuffer shareHandle, EGLenum buftype,
EGLClientBuffer clientBuffer,
const AttributeMap &attribs) const AttributeMap &attribs)
: Surface(EGL_PBUFFER_BIT, config, attribs) : Surface(EGL_PBUFFER_BIT, config, attribs)
{ {
mImplementation = mImplementation =
implFactory->createPbufferFromClientBuffer(mState, config, shareHandle, attribs); implFactory->createPbufferFromClientBuffer(mState, config, buftype, clientBuffer, attribs);
} }
PbufferSurface::~PbufferSurface() PbufferSurface::~PbufferSurface()
......
...@@ -164,7 +164,8 @@ class PbufferSurface final : public Surface ...@@ -164,7 +164,8 @@ class PbufferSurface final : public Surface
const AttributeMap &attribs); const AttributeMap &attribs);
PbufferSurface(rx::EGLImplFactory *implFactory, PbufferSurface(rx::EGLImplFactory *implFactory,
const Config *config, const Config *config,
EGLClientBuffer shareHandle, EGLenum buftype,
EGLClientBuffer clientBuffer,
const AttributeMap &attribs); const AttributeMap &attribs);
~PbufferSurface() override; ~PbufferSurface() override;
}; };
......
...@@ -41,6 +41,15 @@ const egl::DisplayExtensions &DisplayImpl::getExtensions() const ...@@ -41,6 +41,15 @@ const egl::DisplayExtensions &DisplayImpl::getExtensions() const
return mExtensions; return mExtensions;
} }
egl::Error DisplayImpl::validateClientBuffer(const egl::Config *configuration,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) const
{
UNREACHABLE();
return egl::Error(EGL_BAD_DISPLAY, "DisplayImpl::validateClientBuffer unimplemented.");
}
const egl::Caps &DisplayImpl::getCaps() const const egl::Caps &DisplayImpl::getCaps() const
{ {
if (!mCapsInitialized) if (!mCapsInitialized)
......
...@@ -59,6 +59,10 @@ class DisplayImpl : public EGLImplFactory ...@@ -59,6 +59,10 @@ class DisplayImpl : public EGLImplFactory
virtual egl::Error restoreLostDevice() = 0; virtual egl::Error restoreLostDevice() = 0;
virtual bool isValidNativeWindow(EGLNativeWindowType window) const = 0; virtual bool isValidNativeWindow(EGLNativeWindowType window) const = 0;
virtual egl::Error validateClientBuffer(const egl::Config *configuration,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) const;
virtual std::string getVendorString() const = 0; virtual std::string getVendorString() const = 0;
......
...@@ -47,7 +47,8 @@ class EGLImplFactory : angle::NonCopyable ...@@ -47,7 +47,8 @@ class EGLImplFactory : angle::NonCopyable
const egl::AttributeMap &attribs) = 0; const egl::AttributeMap &attribs) = 0;
virtual SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state, virtual SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state,
const egl::Config *configuration, const egl::Config *configuration,
EGLClientBuffer shareHandle, EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) = 0; const egl::AttributeMap &attribs) = 0;
virtual SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state, virtual SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state,
const egl::Config *configuration, const egl::Config *configuration,
......
...@@ -176,16 +176,18 @@ SurfaceImpl *DisplayD3D::createPbufferSurface(const egl::SurfaceState &state, ...@@ -176,16 +176,18 @@ SurfaceImpl *DisplayD3D::createPbufferSurface(const egl::SurfaceState &state,
const egl::AttributeMap &attribs) const egl::AttributeMap &attribs)
{ {
ASSERT(mRenderer != nullptr); ASSERT(mRenderer != nullptr);
return new PbufferSurfaceD3D(state, mRenderer, mDisplay, configuration, nullptr, attribs); return new PbufferSurfaceD3D(state, mRenderer, mDisplay, configuration, 0, nullptr, attribs);
} }
SurfaceImpl *DisplayD3D::createPbufferFromClientBuffer(const egl::SurfaceState &state, SurfaceImpl *DisplayD3D::createPbufferFromClientBuffer(const egl::SurfaceState &state,
const egl::Config *configuration, const egl::Config *configuration,
EGLClientBuffer shareHandle, EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) const egl::AttributeMap &attribs)
{ {
ASSERT(mRenderer != nullptr); ASSERT(mRenderer != nullptr);
return new PbufferSurfaceD3D(state, mRenderer, mDisplay, configuration, shareHandle, attribs); return new PbufferSurfaceD3D(state, mRenderer, mDisplay, configuration, buftype, clientBuffer,
attribs);
} }
SurfaceImpl *DisplayD3D::createPixmapSurface(const egl::SurfaceState &state, SurfaceImpl *DisplayD3D::createPixmapSurface(const egl::SurfaceState &state,
...@@ -291,6 +293,26 @@ bool DisplayD3D::isValidNativeWindow(EGLNativeWindowType window) const ...@@ -291,6 +293,26 @@ bool DisplayD3D::isValidNativeWindow(EGLNativeWindowType window) const
return mRenderer->isValidNativeWindow(window); return mRenderer->isValidNativeWindow(window);
} }
egl::Error DisplayD3D::validateClientBuffer(const egl::Config *configuration,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) const
{
switch (buftype)
{
case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE:
return mRenderer->validateShareHandle(configuration, static_cast<HANDLE>(clientBuffer),
attribs);
case EGL_D3D_TEXTURE_ANGLE:
return mRenderer->getD3DTextureInfo(static_cast<IUnknown *>(clientBuffer), nullptr,
nullptr, nullptr);
default:
return DisplayImpl::validateClientBuffer(configuration, buftype, clientBuffer, attribs);
}
}
void DisplayD3D::generateExtensions(egl::DisplayExtensions *outExtensions) const void DisplayD3D::generateExtensions(egl::DisplayExtensions *outExtensions) const
{ {
mRenderer->generateDisplayExtensions(outExtensions); mRenderer->generateDisplayExtensions(outExtensions);
......
...@@ -34,7 +34,8 @@ class DisplayD3D : public DisplayImpl ...@@ -34,7 +34,8 @@ class DisplayD3D : public DisplayImpl
const egl::AttributeMap &attribs) override; const egl::AttributeMap &attribs) override;
SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state, SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state,
const egl::Config *configuration, const egl::Config *configuration,
EGLClientBuffer shareHandle, EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) override; const egl::AttributeMap &attribs) override;
SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state, SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state,
const egl::Config *configuration, const egl::Config *configuration,
...@@ -59,6 +60,10 @@ class DisplayD3D : public DisplayImpl ...@@ -59,6 +60,10 @@ class DisplayD3D : public DisplayImpl
egl::Error restoreLostDevice() override; egl::Error restoreLostDevice() override;
bool isValidNativeWindow(EGLNativeWindowType window) const override; bool isValidNativeWindow(EGLNativeWindowType window) const override;
egl::Error validateClientBuffer(const egl::Config *configuration,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) const override;
egl::Error getDevice(DeviceImpl **device) override; egl::Error getDevice(DeviceImpl **device) override;
......
...@@ -127,9 +127,17 @@ class RendererD3D : public BufferFactoryD3D ...@@ -127,9 +127,17 @@ class RendererD3D : public BufferFactoryD3D
virtual SwapChainD3D *createSwapChain(NativeWindowD3D *nativeWindow, virtual SwapChainD3D *createSwapChain(NativeWindowD3D *nativeWindow,
HANDLE shareHandle, HANDLE shareHandle,
IUnknown *d3dTexture,
GLenum backBufferFormat, GLenum backBufferFormat,
GLenum depthBufferFormat, GLenum depthBufferFormat,
EGLint orientation) = 0; EGLint orientation) = 0;
virtual egl::Error getD3DTextureInfo(IUnknown *d3dTexture,
EGLint *width,
EGLint *height,
GLenum *fboFormat) const = 0;
virtual egl::Error validateShareHandle(const egl::Config *config,
HANDLE shareHandle,
const egl::AttributeMap &attribs) const = 0;
virtual gl::Error setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &sampler) = 0; virtual gl::Error setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &sampler) = 0;
virtual gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture) = 0; virtual gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture) = 0;
......
...@@ -26,7 +26,8 @@ SurfaceD3D::SurfaceD3D(const egl::SurfaceState &state, ...@@ -26,7 +26,8 @@ SurfaceD3D::SurfaceD3D(const egl::SurfaceState &state,
egl::Display *display, egl::Display *display,
const egl::Config *config, const egl::Config *config,
EGLNativeWindowType window, EGLNativeWindowType window,
EGLClientBuffer shareHandle, EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) const egl::AttributeMap &attribs)
: SurfaceImpl(state), : SurfaceImpl(state),
mRenderer(renderer), mRenderer(renderer),
...@@ -41,19 +42,39 @@ SurfaceD3D::SurfaceD3D(const egl::SurfaceState &state, ...@@ -41,19 +42,39 @@ SurfaceD3D::SurfaceD3D(const egl::SurfaceState &state,
mWidth(static_cast<EGLint>(attribs.get(EGL_WIDTH, 0))), mWidth(static_cast<EGLint>(attribs.get(EGL_WIDTH, 0))),
mHeight(static_cast<EGLint>(attribs.get(EGL_HEIGHT, 0))), mHeight(static_cast<EGLint>(attribs.get(EGL_HEIGHT, 0))),
mSwapInterval(1), mSwapInterval(1),
mShareHandle(reinterpret_cast<HANDLE *>(shareHandle)) mShareHandle(0),
mD3DTexture(nullptr)
{ {
if (window != nullptr && !mFixedSize) if (window != nullptr && !mFixedSize)
{ {
mWidth = -1; mWidth = -1;
mHeight = -1; mHeight = -1;
} }
switch (buftype)
{
case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE:
mShareHandle = static_cast<HANDLE>(clientBuffer);
break;
case EGL_D3D_TEXTURE_ANGLE:
mD3DTexture = static_cast<IUnknown *>(clientBuffer);
ASSERT(mD3DTexture != nullptr);
mD3DTexture->AddRef();
mRenderer->getD3DTextureInfo(mD3DTexture, &mWidth, &mHeight, &mRenderTargetFormat);
mDepthStencilFormat = GL_NONE;
break;
default:
break;
}
} }
SurfaceD3D::~SurfaceD3D() SurfaceD3D::~SurfaceD3D()
{ {
releaseSwapChain(); releaseSwapChain();
SafeDelete(mNativeWindow); SafeDelete(mNativeWindow);
SafeRelease(mD3DTexture);
} }
void SurfaceD3D::releaseSwapChain() void SurfaceD3D::releaseSwapChain()
...@@ -127,8 +148,8 @@ egl::Error SurfaceD3D::resetSwapChain() ...@@ -127,8 +148,8 @@ egl::Error SurfaceD3D::resetSwapChain()
height = mHeight; height = mHeight;
} }
mSwapChain = mRenderer->createSwapChain(mNativeWindow, mShareHandle, mRenderTargetFormat, mSwapChain = mRenderer->createSwapChain(mNativeWindow, mShareHandle, mD3DTexture,
mDepthStencilFormat, mOrientation); mRenderTargetFormat, mDepthStencilFormat, mOrientation);
if (!mSwapChain) if (!mSwapChain)
{ {
return egl::Error(EGL_BAD_ALLOC); return egl::Error(EGL_BAD_ALLOC);
...@@ -346,7 +367,14 @@ WindowSurfaceD3D::WindowSurfaceD3D(const egl::SurfaceState &state, ...@@ -346,7 +367,14 @@ WindowSurfaceD3D::WindowSurfaceD3D(const egl::SurfaceState &state,
const egl::Config *config, const egl::Config *config,
EGLNativeWindowType window, EGLNativeWindowType window,
const egl::AttributeMap &attribs) const egl::AttributeMap &attribs)
: SurfaceD3D(state, renderer, display, config, window, static_cast<EGLClientBuffer>(0), attribs) : SurfaceD3D(state,
renderer,
display,
config,
window,
0,
static_cast<EGLClientBuffer>(0),
attribs)
{ {
} }
...@@ -358,14 +386,16 @@ PbufferSurfaceD3D::PbufferSurfaceD3D(const egl::SurfaceState &state, ...@@ -358,14 +386,16 @@ PbufferSurfaceD3D::PbufferSurfaceD3D(const egl::SurfaceState &state,
RendererD3D *renderer, RendererD3D *renderer,
egl::Display *display, egl::Display *display,
const egl::Config *config, const egl::Config *config,
EGLClientBuffer shareHandle, EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) const egl::AttributeMap &attribs)
: SurfaceD3D(state, : SurfaceD3D(state,
renderer, renderer,
display, display,
config, config,
static_cast<EGLNativeWindowType>(0), static_cast<EGLNativeWindowType>(0),
shareHandle, buftype,
clientBuffer,
attribs) attribs)
{ {
} }
......
...@@ -62,7 +62,8 @@ class SurfaceD3D : public SurfaceImpl ...@@ -62,7 +62,8 @@ class SurfaceD3D : public SurfaceImpl
egl::Display *display, egl::Display *display,
const egl::Config *config, const egl::Config *config,
EGLNativeWindowType window, EGLNativeWindowType window,
EGLClientBuffer shareHandle, EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs); const egl::AttributeMap &attribs);
egl::Error swapRect(EGLint x, EGLint y, EGLint width, EGLint height); egl::Error swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
...@@ -88,6 +89,7 @@ class SurfaceD3D : public SurfaceImpl ...@@ -88,6 +89,7 @@ class SurfaceD3D : public SurfaceImpl
EGLint mSwapInterval; EGLint mSwapInterval;
HANDLE mShareHandle; HANDLE mShareHandle;
IUnknown *mD3DTexture;
}; };
class WindowSurfaceD3D : public SurfaceD3D class WindowSurfaceD3D : public SurfaceD3D
...@@ -109,7 +111,8 @@ class PbufferSurfaceD3D : public SurfaceD3D ...@@ -109,7 +111,8 @@ class PbufferSurfaceD3D : public SurfaceD3D
RendererD3D *renderer, RendererD3D *renderer,
egl::Display *display, egl::Display *display,
const egl::Config *config, const egl::Config *config,
EGLClientBuffer shareHandle, EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs); const egl::AttributeMap &attribs);
~PbufferSurfaceD3D() override; ~PbufferSurfaceD3D() override;
}; };
......
//
// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// SwapChainD3D.cpp: Defines a back-end specific class that hides the details of the
// implementation-specific swapchain.
#include "libANGLE/renderer/d3d/SwapChainD3D.h"
namespace rx
{
SwapChainD3D::SwapChainD3D(HANDLE shareHandle,
IUnknown *d3dTexture,
GLenum backBufferFormat,
GLenum depthBufferFormat)
: mOffscreenRenderTargetFormat(backBufferFormat),
mDepthBufferFormat(depthBufferFormat),
mShareHandle(shareHandle),
mD3DTexture(d3dTexture)
{
if (mD3DTexture)
{
mD3DTexture->AddRef();
}
}
SwapChainD3D::~SwapChainD3D()
{
SafeRelease(mD3DTexture);
}
} // namespace rx
...@@ -29,14 +29,11 @@ class RenderTargetD3D; ...@@ -29,14 +29,11 @@ class RenderTargetD3D;
class SwapChainD3D : angle::NonCopyable class SwapChainD3D : angle::NonCopyable
{ {
public: public:
SwapChainD3D(HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) SwapChainD3D(HANDLE shareHandle,
: mOffscreenRenderTargetFormat(backBufferFormat), IUnknown *d3dTexture,
mDepthBufferFormat(depthBufferFormat), GLenum backBufferFormat,
mShareHandle(shareHandle) GLenum depthBufferFormat);
{ virtual ~SwapChainD3D();
}
virtual ~SwapChainD3D() {};
virtual EGLint resize(EGLint backbufferWidth, EGLint backbufferSize) = 0; virtual EGLint resize(EGLint backbufferWidth, EGLint backbufferSize) = 0;
virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval) = 0; virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval) = 0;
...@@ -59,7 +56,8 @@ class SwapChainD3D : angle::NonCopyable ...@@ -59,7 +56,8 @@ class SwapChainD3D : angle::NonCopyable
const GLenum mDepthBufferFormat; const GLenum mDepthBufferFormat;
HANDLE mShareHandle; HANDLE mShareHandle;
IUnknown *mD3DTexture;
}; };
} } // namespace rx
#endif // LIBANGLE_RENDERER_D3D_SWAPCHAIND3D_H_ #endif // LIBANGLE_RENDERER_D3D_SWAPCHAIND3D_H_
...@@ -1081,6 +1081,7 @@ void Renderer11::generateDisplayExtensions(egl::DisplayExtensions *outExtensions ...@@ -1081,6 +1081,7 @@ void Renderer11::generateDisplayExtensions(egl::DisplayExtensions *outExtensions
outExtensions->d3dShareHandleClientBuffer = true; outExtensions->d3dShareHandleClientBuffer = true;
outExtensions->surfaceD3DTexture2DShareHandle = true; outExtensions->surfaceD3DTexture2DShareHandle = true;
} }
outExtensions->d3dTextureClientBuffer = true;
outExtensions->keyedMutex = true; outExtensions->keyedMutex = true;
outExtensions->querySurfacePointer = true; outExtensions->querySurfacePointer = true;
...@@ -1193,14 +1194,119 @@ NativeWindowD3D *Renderer11::createNativeWindow(EGLNativeWindowType window, ...@@ -1193,14 +1194,119 @@ NativeWindowD3D *Renderer11::createNativeWindow(EGLNativeWindowType window,
#endif #endif
} }
egl::Error Renderer11::getD3DTextureInfo(IUnknown *d3dTexture,
EGLint *width,
EGLint *height,
GLenum *fboFormat) const
{
ID3D11Texture2D *texture = d3d11::DynamicCastComObject<ID3D11Texture2D>(d3dTexture);
if (texture == nullptr)
{
return egl::Error(EGL_BAD_PARAMETER, "client buffer is not a ID3D11Texture2D");
}
ID3D11Device *textureDevice = nullptr;
texture->GetDevice(&textureDevice);
if (textureDevice != mDevice)
{
SafeRelease(texture);
return egl::Error(EGL_BAD_PARAMETER, "Texture's device does not match.");
}
SafeRelease(textureDevice);
D3D11_TEXTURE2D_DESC desc = {0};
texture->GetDesc(&desc);
SafeRelease(texture);
if (width)
{
*width = static_cast<EGLint>(desc.Width);
}
if (height)
{
*height = static_cast<EGLint>(desc.Height);
}
// From table egl.restrictions in EGL_ANGLE_d3d_texture_client_buffer.
switch (desc.Format)
{
case DXGI_FORMAT_R8G8B8A8_UNORM:
case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
case DXGI_FORMAT_B8G8R8A8_UNORM:
case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
case DXGI_FORMAT_R16G16B16A16_FLOAT:
case DXGI_FORMAT_R32G32B32A32_FLOAT:
break;
default:
return egl::Error(EGL_BAD_PARAMETER, "Unknown client buffer texture format: %u.",
desc.Format);
}
if (fboFormat)
{
const angle::Format &angleFormat = d3d11_angle::GetFormat(desc.Format);
*fboFormat = angleFormat.fboImplementationInternalFormat;
}
return egl::Error(EGL_SUCCESS);
}
egl::Error Renderer11::validateShareHandle(const egl::Config *config,
HANDLE shareHandle,
const egl::AttributeMap &attribs) const
{
if (shareHandle == nullptr)
{
return egl::Error(EGL_BAD_PARAMETER, "NULL share handle.");
}
ID3D11Resource *tempResource11 = nullptr;
HRESULT result = mDevice->OpenSharedResource(shareHandle, __uuidof(ID3D11Resource),
(void **)&tempResource11);
if (FAILED(result))
{
return egl::Error(EGL_BAD_PARAMETER, "Failed to open share handle, result: 0x%X.", result);
}
ID3D11Texture2D *texture2D = d3d11::DynamicCastComObject<ID3D11Texture2D>(tempResource11);
SafeRelease(tempResource11);
if (texture2D == nullptr)
{
return egl::Error(EGL_BAD_PARAMETER,
"Failed to query ID3D11Texture2D object from share handle.");
}
D3D11_TEXTURE2D_DESC desc = {0};
texture2D->GetDesc(&desc);
SafeRelease(texture2D);
EGLint width = attribs.getAsInt(EGL_WIDTH, 0);
EGLint height = attribs.getAsInt(EGL_HEIGHT, 0);
ASSERT(width != 0 && height != 0);
const d3d11::Format &backbufferFormatInfo =
d3d11::Format::Get(config->renderTargetFormat, getRenderer11DeviceCaps());
if (desc.Width != static_cast<UINT>(width) || desc.Height != static_cast<UINT>(height) ||
desc.Format != backbufferFormatInfo.texFormat || desc.MipLevels != 1 || desc.ArraySize != 1)
{
return egl::Error(EGL_BAD_PARAMETER, "Invalid texture parameters in share handle texture.");
}
return egl::Error(EGL_SUCCESS);
}
SwapChainD3D *Renderer11::createSwapChain(NativeWindowD3D *nativeWindow, SwapChainD3D *Renderer11::createSwapChain(NativeWindowD3D *nativeWindow,
HANDLE shareHandle, HANDLE shareHandle,
IUnknown *d3dTexture,
GLenum backBufferFormat, GLenum backBufferFormat,
GLenum depthBufferFormat, GLenum depthBufferFormat,
EGLint orientation) EGLint orientation)
{ {
return new SwapChain11(this, GetAs<NativeWindow11>(nativeWindow), shareHandle, backBufferFormat, return new SwapChain11(this, GetAs<NativeWindow11>(nativeWindow), shareHandle, d3dTexture,
depthBufferFormat, orientation); backBufferFormat, depthBufferFormat, orientation);
} }
void *Renderer11::getD3DDevice() void *Renderer11::getD3DDevice()
......
...@@ -123,9 +123,17 @@ class Renderer11 : public RendererD3D ...@@ -123,9 +123,17 @@ class Renderer11 : public RendererD3D
SwapChainD3D *createSwapChain(NativeWindowD3D *nativeWindow, SwapChainD3D *createSwapChain(NativeWindowD3D *nativeWindow,
HANDLE shareHandle, HANDLE shareHandle,
IUnknown *d3dTexture,
GLenum backBufferFormat, GLenum backBufferFormat,
GLenum depthBufferFormat, GLenum depthBufferFormat,
EGLint orientation) override; EGLint orientation) override;
egl::Error getD3DTextureInfo(IUnknown *d3dTexture,
EGLint *width,
EGLint *height,
GLenum *fboFormat) const override;
egl::Error validateShareHandle(const egl::Config *config,
HANDLE shareHandle,
const egl::AttributeMap &attribs) const override;
gl::Error setSamplerState(gl::SamplerType type, gl::Error setSamplerState(gl::SamplerType type,
int index, int index,
...@@ -334,7 +342,7 @@ class Renderer11 : public RendererD3D ...@@ -334,7 +342,7 @@ class Renderer11 : public RendererD3D
bool colorBlit, bool depthBlit, bool stencilBlit); bool colorBlit, bool depthBlit, bool stencilBlit);
bool isES3Capable() const; bool isES3Capable() const;
const Renderer11DeviceCaps &getRenderer11DeviceCaps() { return mRenderer11DeviceCaps; }; const Renderer11DeviceCaps &getRenderer11DeviceCaps() const { return mRenderer11DeviceCaps; };
RendererClass getRendererClass() const override { return RENDERER_D3D11; } RendererClass getRendererClass() const override { return RENDERER_D3D11; }
InputLayoutCache *getInputLayoutCache() { return &mInputLayoutCache; } InputLayoutCache *getInputLayoutCache() { return &mInputLayoutCache; }
......
...@@ -51,10 +51,11 @@ bool NeedsOffscreenTexture(Renderer11 *renderer, NativeWindow11 *nativeWindow, E ...@@ -51,10 +51,11 @@ bool NeedsOffscreenTexture(Renderer11 *renderer, NativeWindow11 *nativeWindow, E
SwapChain11::SwapChain11(Renderer11 *renderer, SwapChain11::SwapChain11(Renderer11 *renderer,
NativeWindow11 *nativeWindow, NativeWindow11 *nativeWindow,
HANDLE shareHandle, HANDLE shareHandle,
IUnknown *d3dTexture,
GLenum backBufferFormat, GLenum backBufferFormat,
GLenum depthBufferFormat, GLenum depthBufferFormat,
EGLint orientation) EGLint orientation)
: SwapChainD3D(shareHandle, backBufferFormat, depthBufferFormat), : SwapChainD3D(shareHandle, d3dTexture, backBufferFormat, depthBufferFormat),
mRenderer(renderer), mRenderer(renderer),
mWidth(-1), mWidth(-1),
mHeight(-1), mHeight(-1),
...@@ -194,42 +195,29 @@ EGLint SwapChain11::resetOffscreenColorBuffer(int backbufferWidth, int backbuffe ...@@ -194,42 +195,29 @@ EGLint SwapChain11::resetOffscreenColorBuffer(int backbufferWidth, int backbuffe
const d3d11::Format &backbufferFormatInfo = const d3d11::Format &backbufferFormatInfo =
d3d11::Format::Get(mOffscreenRenderTargetFormat, mRenderer->getRenderer11DeviceCaps()); d3d11::Format::Get(mOffscreenRenderTargetFormat, mRenderer->getRenderer11DeviceCaps());
// If the app passed in a share handle, open the resource // If the app passed in a share handle or D3D texture, open the resource
// See EGL_ANGLE_d3d_share_handle_client_buffer // See EGL_ANGLE_d3d_share_handle_client_buffer and EGL_ANGLE_d3d_texture_client_buffer
if (mAppCreatedShareHandle) if (mAppCreatedShareHandle || mD3DTexture != nullptr)
{ {
ID3D11Resource *tempResource11; if (mAppCreatedShareHandle)
HRESULT result = device->OpenSharedResource(mShareHandle, __uuidof(ID3D11Resource), (void**)&tempResource11);
if (FAILED(result))
{ {
ERR("Failed to open the swap chain pbuffer share handle: %08lX", result); ID3D11Resource *tempResource11;
release(); HRESULT result = device->OpenSharedResource(mShareHandle, __uuidof(ID3D11Resource),
return EGL_BAD_PARAMETER; (void **)&tempResource11);
} ASSERT(SUCCEEDED(result));
result = tempResource11->QueryInterface(__uuidof(ID3D11Texture2D), (void**)&mOffscreenTexture);
SafeRelease(tempResource11);
if (FAILED(result)) mOffscreenTexture = d3d11::DynamicCastComObject<ID3D11Texture2D>(tempResource11);
SafeRelease(tempResource11);
ASSERT(SUCCEEDED(mOffscreenTexture != nullptr));
}
else if (mD3DTexture != nullptr)
{ {
ERR("Failed to query texture2d interface in pbuffer share handle: %08lX", result); mOffscreenTexture = d3d11::DynamicCastComObject<ID3D11Texture2D>(mD3DTexture);
release(); ASSERT(mOffscreenTexture != nullptr);
return EGL_BAD_PARAMETER;
} }
else
// Validate offscreen texture parameters
D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0};
mOffscreenTexture->GetDesc(&offscreenTextureDesc);
if (offscreenTextureDesc.Width != (UINT)backbufferWidth ||
offscreenTextureDesc.Height != (UINT)backbufferHeight ||
offscreenTextureDesc.Format != backbufferFormatInfo.texFormat ||
offscreenTextureDesc.MipLevels != 1 || offscreenTextureDesc.ArraySize != 1)
{ {
ERR("Invalid texture parameters in the shared offscreen texture pbuffer"); UNREACHABLE();
release();
return EGL_BAD_PARAMETER;
} }
} }
else else
......
...@@ -24,6 +24,7 @@ class SwapChain11 final : public SwapChainD3D ...@@ -24,6 +24,7 @@ class SwapChain11 final : public SwapChainD3D
SwapChain11(Renderer11 *renderer, SwapChain11(Renderer11 *renderer,
NativeWindow11 *nativeWindow, NativeWindow11 *nativeWindow,
HANDLE shareHandle, HANDLE shareHandle,
IUnknown *d3dTexture,
GLenum backBufferFormat, GLenum backBufferFormat,
GLenum depthBufferFormat, GLenum depthBufferFormat,
EGLint orientation); EGLint orientation);
......
...@@ -60,6 +60,11 @@ GLenum GetComponentType(DXGI_FORMAT dxgiFormat); ...@@ -60,6 +60,11 @@ GLenum GetComponentType(DXGI_FORMAT dxgiFormat);
} // namespace d3d11 } // namespace d3d11
namespace d3d11_angle
{
const angle::Format &GetFormat(DXGI_FORMAT dxgiFormat);
}
} // namespace rx } // namespace rx
#endif // LIBANGLE_RENDERER_D3D_D3D11_FORMATUTILS11_H_ #endif // LIBANGLE_RENDERER_D3D_D3D11_FORMATUTILS11_H_
...@@ -525,6 +525,7 @@ void Renderer9::generateDisplayExtensions(egl::DisplayExtensions *outExtensions) ...@@ -525,6 +525,7 @@ void Renderer9::generateDisplayExtensions(egl::DisplayExtensions *outExtensions)
outExtensions->d3dShareHandleClientBuffer = true; outExtensions->d3dShareHandleClientBuffer = true;
outExtensions->surfaceD3DTexture2DShareHandle = true; outExtensions->surfaceD3DTexture2DShareHandle = true;
} }
outExtensions->d3dTextureClientBuffer = true;
outExtensions->querySurfacePointer = true; outExtensions->querySurfacePointer = true;
outExtensions->windowFixedSize = true; outExtensions->windowFixedSize = true;
...@@ -672,12 +673,111 @@ NativeWindowD3D *Renderer9::createNativeWindow(EGLNativeWindowType window, ...@@ -672,12 +673,111 @@ NativeWindowD3D *Renderer9::createNativeWindow(EGLNativeWindowType window,
SwapChainD3D *Renderer9::createSwapChain(NativeWindowD3D *nativeWindow, SwapChainD3D *Renderer9::createSwapChain(NativeWindowD3D *nativeWindow,
HANDLE shareHandle, HANDLE shareHandle,
IUnknown *d3dTexture,
GLenum backBufferFormat, GLenum backBufferFormat,
GLenum depthBufferFormat, GLenum depthBufferFormat,
EGLint orientation) EGLint orientation)
{ {
return new SwapChain9(this, GetAs<NativeWindow9>(nativeWindow), shareHandle, backBufferFormat, return new SwapChain9(this, GetAs<NativeWindow9>(nativeWindow), shareHandle, d3dTexture,
depthBufferFormat, orientation); backBufferFormat, depthBufferFormat, orientation);
}
egl::Error Renderer9::getD3DTextureInfo(IUnknown *d3dTexture,
EGLint *width,
EGLint *height,
GLenum *fboFormat) const
{
IDirect3DTexture9 *texture = nullptr;
if (FAILED(d3dTexture->QueryInterface(&texture)))
{
return egl::Error(EGL_BAD_PARAMETER, "client buffer is not a IDirect3DTexture9");
}
IDirect3DDevice9 *textureDevice = nullptr;
texture->GetDevice(&textureDevice);
if (textureDevice != mDevice)
{
SafeRelease(texture);
return egl::Error(EGL_BAD_PARAMETER, "Texture's device does not match.");
}
SafeRelease(textureDevice);
D3DSURFACE_DESC desc;
texture->GetLevelDesc(0, &desc);
SafeRelease(texture);
if (width)
{
*width = static_cast<EGLint>(desc.Width);
}
if (height)
{
*height = static_cast<EGLint>(desc.Height);
}
// From table egl.restrictions in EGL_ANGLE_d3d_texture_client_buffer.
switch (desc.Format)
{
case D3DFMT_R8G8B8:
case D3DFMT_A8R8G8B8:
case D3DFMT_A16B16G16R16F:
case D3DFMT_A32B32G32R32F:
break;
default:
return egl::Error(EGL_BAD_PARAMETER, "Unknown client buffer texture format: %u.",
desc.Format);
}
if (fboFormat)
{
const auto &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format);
ASSERT(d3dFormatInfo.info != nullptr);
*fboFormat = d3dFormatInfo.info->fboImplementationInternalFormat;
}
return egl::Error(EGL_SUCCESS);
}
egl::Error Renderer9::validateShareHandle(const egl::Config *config,
HANDLE shareHandle,
const egl::AttributeMap &attribs) const
{
if (shareHandle == nullptr)
{
return egl::Error(EGL_BAD_PARAMETER, "NULL share handle.");
}
EGLint width = attribs.getAsInt(EGL_WIDTH, 0);
EGLint height = attribs.getAsInt(EGL_HEIGHT, 0);
ASSERT(width != 0 && height != 0);
const d3d9::TextureFormat &backBufferd3dFormatInfo =
d3d9::GetTextureFormatInfo(config->renderTargetFormat);
IDirect3DTexture9 *texture = nullptr;
HRESULT result = mDevice->CreateTexture(width, height, 1, D3DUSAGE_RENDERTARGET,
backBufferd3dFormatInfo.texFormat, D3DPOOL_DEFAULT,
&texture, &shareHandle);
if (FAILED(result))
{
return egl::Error(EGL_BAD_PARAMETER, "Failed to open share handle, result: 0x%X.", result);
}
DWORD levelCount = texture->GetLevelCount();
D3DSURFACE_DESC desc;
texture->GetLevelDesc(0, &desc);
SafeRelease(texture);
if (levelCount != 1 || desc.Width != static_cast<UINT>(width) ||
desc.Height != static_cast<UINT>(height) ||
desc.Format != backBufferd3dFormatInfo.texFormat)
{
return egl::Error(EGL_BAD_PARAMETER, "Invalid texture parameters in share handle texture.");
}
return egl::Error(EGL_SUCCESS);
} }
ContextImpl *Renderer9::createContext(const gl::ContextState &state) ContextImpl *Renderer9::createContext(const gl::ContextState &state)
......
...@@ -88,9 +88,17 @@ class Renderer9 : public RendererD3D ...@@ -88,9 +88,17 @@ class Renderer9 : public RendererD3D
SwapChainD3D *createSwapChain(NativeWindowD3D *nativeWindow, SwapChainD3D *createSwapChain(NativeWindowD3D *nativeWindow,
HANDLE shareHandle, HANDLE shareHandle,
IUnknown *d3dTexture,
GLenum backBufferFormat, GLenum backBufferFormat,
GLenum depthBufferFormat, GLenum depthBufferFormat,
EGLint orientation) override; EGLint orientation) override;
egl::Error getD3DTextureInfo(IUnknown *d3dTexture,
EGLint *width,
EGLint *height,
GLenum *fboFormat) const override;
egl::Error validateShareHandle(const egl::Config *config,
HANDLE shareHandle,
const egl::AttributeMap &attribs) const override;
ContextImpl *createContext(const gl::ContextState &state) override; ContextImpl *createContext(const gl::ContextState &state) override;
......
...@@ -19,10 +19,11 @@ namespace rx ...@@ -19,10 +19,11 @@ namespace rx
SwapChain9::SwapChain9(Renderer9 *renderer, SwapChain9::SwapChain9(Renderer9 *renderer,
NativeWindow9 *nativeWindow, NativeWindow9 *nativeWindow,
HANDLE shareHandle, HANDLE shareHandle,
IUnknown *d3dTexture,
GLenum backBufferFormat, GLenum backBufferFormat,
GLenum depthBufferFormat, GLenum depthBufferFormat,
EGLint orientation) EGLint orientation)
: SwapChainD3D(shareHandle, backBufferFormat, depthBufferFormat), : SwapChainD3D(shareHandle, d3dTexture, backBufferFormat, depthBufferFormat),
mRenderer(renderer), mRenderer(renderer),
mWidth(-1), mWidth(-1),
mHeight(-1), mHeight(-1),
...@@ -105,28 +106,37 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI ...@@ -105,28 +106,37 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI
SafeRelease(mOffscreenTexture); SafeRelease(mOffscreenTexture);
SafeRelease(mDepthStencil); SafeRelease(mDepthStencil);
HANDLE *pShareHandle = NULL; const d3d9::TextureFormat &backBufferd3dFormatInfo =
if (!mNativeWindow->getNativeWindow() && mRenderer->getShareHandleSupport()) d3d9::GetTextureFormatInfo(mOffscreenRenderTargetFormat);
if (mD3DTexture != nullptr)
{ {
pShareHandle = &mShareHandle; result = mD3DTexture->QueryInterface(&mOffscreenTexture);
ASSERT(SUCCEEDED(result));
} }
else
const d3d9::TextureFormat &backBufferd3dFormatInfo = d3d9::GetTextureFormatInfo(mOffscreenRenderTargetFormat);
result = device->CreateTexture(backbufferWidth, backbufferHeight, 1, D3DUSAGE_RENDERTARGET,
backBufferd3dFormatInfo.texFormat, D3DPOOL_DEFAULT, &mOffscreenTexture,
pShareHandle);
if (FAILED(result))
{ {
ERR("Could not create offscreen texture: %08lX", result); HANDLE *pShareHandle = NULL;
release(); if (!mNativeWindow->getNativeWindow() && mRenderer->getShareHandleSupport())
if (d3d9::isDeviceLostError(result))
{ {
return EGL_CONTEXT_LOST; pShareHandle = &mShareHandle;
} }
else
result = device->CreateTexture(backbufferWidth, backbufferHeight, 1, D3DUSAGE_RENDERTARGET,
backBufferd3dFormatInfo.texFormat, D3DPOOL_DEFAULT,
&mOffscreenTexture, pShareHandle);
if (FAILED(result))
{ {
return EGL_BAD_ALLOC; ERR("Could not create offscreen texture: %08lX", result);
release();
if (d3d9::isDeviceLostError(result))
{
return EGL_CONTEXT_LOST;
}
else
{
return EGL_BAD_ALLOC;
}
} }
} }
......
...@@ -24,6 +24,7 @@ class SwapChain9 : public SwapChainD3D ...@@ -24,6 +24,7 @@ class SwapChain9 : public SwapChainD3D
SwapChain9(Renderer9 *renderer, SwapChain9(Renderer9 *renderer,
NativeWindow9 *nativeWindow, NativeWindow9 *nativeWindow,
HANDLE shareHandle, HANDLE shareHandle,
IUnknown *d3dTexture,
GLenum backBufferFormat, GLenum backBufferFormat,
GLenum depthBufferFormat, GLenum depthBufferFormat,
EGLint orientation); EGLint orientation);
......
...@@ -22,8 +22,7 @@ ...@@ -22,8 +22,7 @@
namespace rx namespace rx
{ {
DisplayGL::DisplayGL() DisplayGL::DisplayGL() : mRenderer(nullptr), mCurrentDrawSurface(nullptr)
: mRenderer(nullptr)
{ {
} }
...@@ -73,6 +72,13 @@ StreamProducerImpl *DisplayGL::createStreamProducerD3DTextureNV12( ...@@ -73,6 +72,13 @@ StreamProducerImpl *DisplayGL::createStreamProducerD3DTextureNV12(
egl::Error DisplayGL::makeCurrent(egl::Surface *drawSurface, egl::Surface *readSurface, gl::Context *context) egl::Error DisplayGL::makeCurrent(egl::Surface *drawSurface, egl::Surface *readSurface, gl::Context *context)
{ {
// Notify the previous surface (if it still exists) that it is no longer current
if (mCurrentDrawSurface && mSurfaceSet.find(mCurrentDrawSurface) != mSurfaceSet.end())
{
ANGLE_TRY(GetImplAs<SurfaceGL>(mCurrentDrawSurface)->unMakeCurrent());
}
mCurrentDrawSurface = nullptr;
if (!drawSurface) if (!drawSurface)
{ {
return egl::Error(EGL_SUCCESS); return egl::Error(EGL_SUCCESS);
...@@ -83,7 +89,10 @@ egl::Error DisplayGL::makeCurrent(egl::Surface *drawSurface, egl::Surface *readS ...@@ -83,7 +89,10 @@ egl::Error DisplayGL::makeCurrent(egl::Surface *drawSurface, egl::Surface *readS
glContext->getStateManager()->pauseTransformFeedback(context->getContextState()); glContext->getStateManager()->pauseTransformFeedback(context->getContextState());
SurfaceGL *glDrawSurface = GetImplAs<SurfaceGL>(drawSurface); SurfaceGL *glDrawSurface = GetImplAs<SurfaceGL>(drawSurface);
return glDrawSurface->makeCurrent(); ANGLE_TRY(glDrawSurface->makeCurrent());
mCurrentDrawSurface = drawSurface;
return egl::Error(EGL_SUCCESS);
} }
gl::Version DisplayGL::getMaxSupportedESVersion() const gl::Version DisplayGL::getMaxSupportedESVersion() const
......
...@@ -12,6 +12,11 @@ ...@@ -12,6 +12,11 @@
#include "libANGLE/renderer/DisplayImpl.h" #include "libANGLE/renderer/DisplayImpl.h"
#include "libANGLE/renderer/gl/FunctionsGL.h" #include "libANGLE/renderer/gl/FunctionsGL.h"
namespace egl
{
class Surface;
}
namespace rx namespace rx
{ {
...@@ -48,6 +53,8 @@ class DisplayGL : public DisplayImpl ...@@ -48,6 +53,8 @@ class DisplayGL : public DisplayImpl
virtual const FunctionsGL *getFunctionsGL() const = 0; virtual const FunctionsGL *getFunctionsGL() const = 0;
RendererGL *mRenderer; RendererGL *mRenderer;
egl::Surface *mCurrentDrawSurface;
}; };
} }
......
...@@ -34,4 +34,9 @@ egl::Error SurfaceGL::getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuin ...@@ -34,4 +34,9 @@ egl::Error SurfaceGL::getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuin
UNREACHABLE(); UNREACHABLE();
return egl::Error(EGL_BAD_SURFACE); return egl::Error(EGL_BAD_SURFACE);
} }
egl::Error SurfaceGL::unMakeCurrent()
{
return egl::Error(EGL_SUCCESS);
}
} }
...@@ -26,6 +26,7 @@ class SurfaceGL : public SurfaceImpl ...@@ -26,6 +26,7 @@ class SurfaceGL : public SurfaceImpl
egl::Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) override; egl::Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) override;
virtual egl::Error makeCurrent() = 0; virtual egl::Error makeCurrent() = 0;
virtual egl::Error unMakeCurrent();
private: private:
RendererGL *mRenderer; RendererGL *mRenderer;
......
...@@ -35,7 +35,8 @@ class DisplayCGL : public DisplayGL ...@@ -35,7 +35,8 @@ class DisplayCGL : public DisplayGL
const egl::AttributeMap &attribs) override; const egl::AttributeMap &attribs) override;
SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state, SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state,
const egl::Config *configuration, const egl::Config *configuration,
EGLClientBuffer shareHandle, EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) override; const egl::AttributeMap &attribs) override;
SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state, SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state,
const egl::Config *configuration, const egl::Config *configuration,
......
...@@ -128,7 +128,8 @@ SurfaceImpl *DisplayCGL::createPbufferSurface(const egl::SurfaceState &state, ...@@ -128,7 +128,8 @@ SurfaceImpl *DisplayCGL::createPbufferSurface(const egl::SurfaceState &state,
SurfaceImpl *DisplayCGL::createPbufferFromClientBuffer(const egl::SurfaceState &state, SurfaceImpl *DisplayCGL::createPbufferFromClientBuffer(const egl::SurfaceState &state,
const egl::Config *configuration, const egl::Config *configuration,
EGLClientBuffer shareHandle, EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) const egl::AttributeMap &attribs)
{ {
UNIMPLEMENTED(); UNIMPLEMENTED();
......
...@@ -185,7 +185,8 @@ SurfaceImpl *DisplayAndroid::createPbufferSurface(const egl::SurfaceState &state ...@@ -185,7 +185,8 @@ SurfaceImpl *DisplayAndroid::createPbufferSurface(const egl::SurfaceState &state
SurfaceImpl *DisplayAndroid::createPbufferFromClientBuffer(const egl::SurfaceState &state, SurfaceImpl *DisplayAndroid::createPbufferFromClientBuffer(const egl::SurfaceState &state,
const egl::Config *configuration, const egl::Config *configuration,
EGLClientBuffer shareHandle, EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) const egl::AttributeMap &attribs)
{ {
UNIMPLEMENTED(); UNIMPLEMENTED();
......
...@@ -36,7 +36,8 @@ class DisplayAndroid : public DisplayEGL ...@@ -36,7 +36,8 @@ class DisplayAndroid : public DisplayEGL
const egl::AttributeMap &attribs) override; const egl::AttributeMap &attribs) override;
SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state, SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state,
const egl::Config *configuration, const egl::Config *configuration,
EGLClientBuffer shareHandle, EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) override; const egl::AttributeMap &attribs) override;
SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state, SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state,
const egl::Config *configuration, const egl::Config *configuration,
......
...@@ -859,7 +859,8 @@ SurfaceImpl *DisplayOzone::createPbufferSurface(const egl::SurfaceState &state, ...@@ -859,7 +859,8 @@ SurfaceImpl *DisplayOzone::createPbufferSurface(const egl::SurfaceState &state,
SurfaceImpl *DisplayOzone::createPbufferFromClientBuffer(const egl::SurfaceState &state, SurfaceImpl *DisplayOzone::createPbufferFromClientBuffer(const egl::SurfaceState &state,
const egl::Config *configuration, const egl::Config *configuration,
EGLClientBuffer shareHandle, EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) const egl::AttributeMap &attribs)
{ {
UNIMPLEMENTED(); UNIMPLEMENTED();
......
...@@ -122,7 +122,8 @@ class DisplayOzone final : public DisplayEGL ...@@ -122,7 +122,8 @@ class DisplayOzone final : public DisplayEGL
const egl::AttributeMap &attribs) override; const egl::AttributeMap &attribs) override;
SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state, SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state,
const egl::Config *configuration, const egl::Config *configuration,
EGLClientBuffer shareHandle, EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) override; const egl::AttributeMap &attribs) override;
SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state, SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state,
const egl::Config *configuration, const egl::Config *configuration,
......
...@@ -410,7 +410,8 @@ SurfaceImpl *DisplayGLX::createPbufferSurface(const egl::SurfaceState &state, ...@@ -410,7 +410,8 @@ SurfaceImpl *DisplayGLX::createPbufferSurface(const egl::SurfaceState &state,
SurfaceImpl *DisplayGLX::createPbufferFromClientBuffer(const egl::SurfaceState &state, SurfaceImpl *DisplayGLX::createPbufferFromClientBuffer(const egl::SurfaceState &state,
const egl::Config *configuration, const egl::Config *configuration,
EGLClientBuffer shareHandle, EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) const egl::AttributeMap &attribs)
{ {
UNIMPLEMENTED(); UNIMPLEMENTED();
......
...@@ -53,7 +53,8 @@ class DisplayGLX : public DisplayGL ...@@ -53,7 +53,8 @@ class DisplayGLX : public DisplayGL
const egl::AttributeMap &attribs) override; const egl::AttributeMap &attribs) override;
SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state, SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state,
const egl::Config *configuration, const egl::Config *configuration,
EGLClientBuffer shareHandle, EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) override; const egl::AttributeMap &attribs) override;
SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state, SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state,
const egl::Config *configuration, const egl::Config *configuration,
......
// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// D3DTextureSurfaceWGL.h: WGL implementation of egl::Surface for D3D texture interop.
#ifndef LIBANGLE_RENDERER_GL_WGL_D3DTEXTIRESURFACEWGL_H_
#define LIBANGLE_RENDERER_GL_WGL_D3DTEXTIRESURFACEWGL_H_
#include "libANGLE/renderer/gl/SurfaceGL.h"
#include <GL/wglext.h>
namespace rx
{
class FunctionsGL;
class FunctionsWGL;
class DisplayWGL;
class StateManagerGL;
struct WorkaroundsGL;
class D3DTextureSurfaceWGL : public SurfaceGL
{
public:
D3DTextureSurfaceWGL(const egl::SurfaceState &state,
RendererGL *renderer,
EGLClientBuffer clientBuffer,
DisplayWGL *display,
HGLRC wglContext,
HDC deviceContext,
const FunctionsGL *functionsGL,
const FunctionsWGL *functionsWGL);
~D3DTextureSurfaceWGL() override;
static egl::Error ValidateD3DTextureClientBuffer(EGLClientBuffer clientBuffer);
egl::Error initialize() override;
egl::Error makeCurrent() override;
egl::Error unMakeCurrent() override;
egl::Error swap() override;
egl::Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) override;
egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) override;
egl::Error bindTexImage(gl::Texture *texture, EGLint buffer) override;
egl::Error releaseTexImage(EGLint buffer) override;
void setSwapInterval(EGLint interval) override;
EGLint getWidth() const override;
EGLint getHeight() const override;
EGLint isPostSubBufferSupported() const override;
EGLint getSwapBehavior() const override;
FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &data) override;
private:
EGLClientBuffer mClientBuffer;
RendererGL *mRenderer;
DisplayWGL *mDisplay;
StateManagerGL *mStateManager;
const WorkaroundsGL &mWorkarounds;
const FunctionsGL *mFunctionsGL;
const FunctionsWGL *mFunctionsWGL;
HGLRC mWGLContext;
HDC mDeviceContext;
size_t mWidth;
size_t mHeight;
HANDLE mDeviceHandle;
IUnknown *mObject;
HANDLE mBoundObjectTextureHandle;
HANDLE mBoundObjectRenderbufferHandle;
GLuint mRenderbufferID;
GLuint mFramebufferID;
};
} // namespace rx
#endif // LIBANGLE_RENDERER_GL_WGL_D3DTEXTIRESURFACEWGL_H_
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "libANGLE/Surface.h" #include "libANGLE/Surface.h"
#include "libANGLE/renderer/gl/RendererGL.h" #include "libANGLE/renderer/gl/RendererGL.h"
#include "libANGLE/renderer/gl/renderergl_utils.h" #include "libANGLE/renderer/gl/renderergl_utils.h"
#include "libANGLE/renderer/gl/wgl/D3DTextureSurfaceWGL.h"
#include "libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.h" #include "libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.h"
#include "libANGLE/renderer/gl/wgl/FunctionsWGL.h" #include "libANGLE/renderer/gl/wgl/FunctionsWGL.h"
#include "libANGLE/renderer/gl/wgl/PbufferSurfaceWGL.h" #include "libANGLE/renderer/gl/wgl/PbufferSurfaceWGL.h"
...@@ -464,11 +465,13 @@ SurfaceImpl *DisplayWGL::createPbufferSurface(const egl::SurfaceState &state, ...@@ -464,11 +465,13 @@ SurfaceImpl *DisplayWGL::createPbufferSurface(const egl::SurfaceState &state,
SurfaceImpl *DisplayWGL::createPbufferFromClientBuffer(const egl::SurfaceState &state, SurfaceImpl *DisplayWGL::createPbufferFromClientBuffer(const egl::SurfaceState &state,
const egl::Config *configuration, const egl::Config *configuration,
EGLClientBuffer shareHandle, EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) const egl::AttributeMap &attribs)
{ {
UNIMPLEMENTED(); ASSERT(buftype == EGL_D3D_TEXTURE_ANGLE);
return nullptr; return new D3DTextureSurfaceWGL(state, getRenderer(), clientBuffer, this, mWGLContext,
mDeviceContext, mFunctionsGL, mFunctionsWGL);
} }
SurfaceImpl *DisplayWGL::createPixmapSurface(const egl::SurfaceState &state, SurfaceImpl *DisplayWGL::createPixmapSurface(const egl::SurfaceState &state,
...@@ -581,6 +584,21 @@ bool DisplayWGL::isValidNativeWindow(EGLNativeWindowType window) const ...@@ -581,6 +584,21 @@ bool DisplayWGL::isValidNativeWindow(EGLNativeWindowType window) const
return (IsWindow(window) == TRUE); return (IsWindow(window) == TRUE);
} }
egl::Error DisplayWGL::validateClientBuffer(const egl::Config *configuration,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) const
{
switch (buftype)
{
case EGL_D3D_TEXTURE_ANGLE:
return D3DTextureSurfaceWGL::ValidateD3DTextureClientBuffer(clientBuffer);
default:
return DisplayGL::validateClientBuffer(configuration, buftype, clientBuffer, attribs);
}
}
std::string DisplayWGL::getVendorString() const std::string DisplayWGL::getVendorString() const
{ {
//UNIMPLEMENTED(); //UNIMPLEMENTED();
...@@ -644,6 +662,8 @@ void DisplayWGL::generateExtensions(egl::DisplayExtensions *outExtensions) const ...@@ -644,6 +662,8 @@ void DisplayWGL::generateExtensions(egl::DisplayExtensions *outExtensions) const
outExtensions->surfaceOrientation = mUseDXGISwapChains; outExtensions->surfaceOrientation = mUseDXGISwapChains;
outExtensions->createContextRobustness = mHasRobustness; outExtensions->createContextRobustness = mHasRobustness;
outExtensions->d3dTextureClientBuffer = mFunctionsWGL->hasExtension("WGL_NV_DX_interop2");
} }
void DisplayWGL::generateCaps(egl::Caps *outCaps) const void DisplayWGL::generateCaps(egl::Caps *outCaps) const
......
...@@ -37,7 +37,8 @@ class DisplayWGL : public DisplayGL ...@@ -37,7 +37,8 @@ class DisplayWGL : public DisplayGL
const egl::AttributeMap &attribs) override; const egl::AttributeMap &attribs) override;
SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state, SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state,
const egl::Config *configuration, const egl::Config *configuration,
EGLClientBuffer shareHandle, EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) override; const egl::AttributeMap &attribs) override;
SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state, SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state,
const egl::Config *configuration, const egl::Config *configuration,
...@@ -50,6 +51,10 @@ class DisplayWGL : public DisplayGL ...@@ -50,6 +51,10 @@ class DisplayWGL : public DisplayGL
egl::Error restoreLostDevice() override; egl::Error restoreLostDevice() override;
bool isValidNativeWindow(EGLNativeWindowType window) const override; bool isValidNativeWindow(EGLNativeWindowType window) const override;
egl::Error validateClientBuffer(const egl::Config *configuration,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) const override;
egl::Error getDevice(DeviceImpl **device) override; egl::Error getDevice(DeviceImpl **device) override;
......
...@@ -116,7 +116,8 @@ SurfaceImpl *DisplayNULL::createPbufferSurface(const egl::SurfaceState &state, ...@@ -116,7 +116,8 @@ SurfaceImpl *DisplayNULL::createPbufferSurface(const egl::SurfaceState &state,
SurfaceImpl *DisplayNULL::createPbufferFromClientBuffer(const egl::SurfaceState &state, SurfaceImpl *DisplayNULL::createPbufferFromClientBuffer(const egl::SurfaceState &state,
const egl::Config *configuration, const egl::Config *configuration,
EGLClientBuffer shareHandle, EGLenum buftype,
EGLClientBuffer buffer,
const egl::AttributeMap &attribs) const egl::AttributeMap &attribs)
{ {
UNIMPLEMENTED(); UNIMPLEMENTED();
......
...@@ -54,7 +54,8 @@ class DisplayNULL : public DisplayImpl ...@@ -54,7 +54,8 @@ class DisplayNULL : public DisplayImpl
const egl::AttributeMap &attribs) override; const egl::AttributeMap &attribs) override;
SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state, SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state,
const egl::Config *configuration, const egl::Config *configuration,
EGLClientBuffer shareHandle, EGLenum buftype,
EGLClientBuffer buffer,
const egl::AttributeMap &attribs) override; const egl::AttributeMap &attribs) override;
SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state, SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state,
const egl::Config *configuration, const egl::Config *configuration,
......
...@@ -111,7 +111,8 @@ SurfaceImpl *DisplayVk::createPbufferSurface(const egl::SurfaceState &state, ...@@ -111,7 +111,8 @@ SurfaceImpl *DisplayVk::createPbufferSurface(const egl::SurfaceState &state,
SurfaceImpl *DisplayVk::createPbufferFromClientBuffer(const egl::SurfaceState &state, SurfaceImpl *DisplayVk::createPbufferFromClientBuffer(const egl::SurfaceState &state,
const egl::Config *configuration, const egl::Config *configuration,
EGLClientBuffer shareHandle, EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) const egl::AttributeMap &attribs)
{ {
UNIMPLEMENTED(); UNIMPLEMENTED();
......
...@@ -54,7 +54,8 @@ class DisplayVk : public DisplayImpl ...@@ -54,7 +54,8 @@ class DisplayVk : public DisplayImpl
const egl::AttributeMap &attribs) override; const egl::AttributeMap &attribs) override;
SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state, SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state,
const egl::Config *configuration, const egl::Config *configuration,
EGLClientBuffer shareHandle, EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) override; const egl::AttributeMap &attribs) override;
SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state, SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state,
const egl::Config *configuration, const egl::Config *configuration,
......
...@@ -653,6 +653,17 @@ Error ValidateCreatePbufferFromClientBuffer(Display *display, EGLenum buftype, E ...@@ -653,6 +653,17 @@ Error ValidateCreatePbufferFromClientBuffer(Display *display, EGLenum buftype, E
} }
break; break;
case EGL_D3D_TEXTURE_ANGLE:
if (!displayExtensions.d3dTextureClientBuffer)
{
return Error(EGL_BAD_PARAMETER);
}
if (buffer == nullptr)
{
return Error(EGL_BAD_PARAMETER);
}
break;
default: default:
return Error(EGL_BAD_PARAMETER); return Error(EGL_BAD_PARAMETER);
} }
...@@ -753,6 +764,8 @@ Error ValidateCreatePbufferFromClientBuffer(Display *display, EGLenum buftype, E ...@@ -753,6 +764,8 @@ Error ValidateCreatePbufferFromClientBuffer(Display *display, EGLenum buftype, E
} }
} }
ANGLE_TRY(display->validateClientBuffer(config, buftype, buffer, attributes));
return Error(EGL_SUCCESS); return Error(EGL_SUCCESS);
} }
......
...@@ -255,6 +255,7 @@ ...@@ -255,6 +255,7 @@
'libANGLE/renderer/d3d/ShaderExecutableD3D.h', 'libANGLE/renderer/d3d/ShaderExecutableD3D.h',
'libANGLE/renderer/d3d/SurfaceD3D.cpp', 'libANGLE/renderer/d3d/SurfaceD3D.cpp',
'libANGLE/renderer/d3d/SurfaceD3D.h', 'libANGLE/renderer/d3d/SurfaceD3D.h',
'libANGLE/renderer/d3d/SwapChainD3D.cpp',
'libANGLE/renderer/d3d/SwapChainD3D.h', 'libANGLE/renderer/d3d/SwapChainD3D.h',
'libANGLE/renderer/d3d/TextureD3D.cpp', 'libANGLE/renderer/d3d/TextureD3D.cpp',
'libANGLE/renderer/d3d/TextureD3D.h', 'libANGLE/renderer/d3d/TextureD3D.h',
...@@ -511,6 +512,8 @@ ...@@ -511,6 +512,8 @@
], ],
'libangle_gl_wgl_sources': 'libangle_gl_wgl_sources':
[ [
'libANGLE/renderer/gl/wgl/D3DTextureSurfaceWGL.cpp',
'libANGLE/renderer/gl/wgl/D3DTextureSurfaceWGL.h',
'libANGLE/renderer/gl/wgl/DisplayWGL.cpp', 'libANGLE/renderer/gl/wgl/DisplayWGL.cpp',
'libANGLE/renderer/gl/wgl/DisplayWGL.h', 'libANGLE/renderer/gl/wgl/DisplayWGL.h',
'libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.cpp', 'libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.cpp',
......
...@@ -1068,7 +1068,8 @@ EGLSurface EGLAPIENTRY CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buf ...@@ -1068,7 +1068,8 @@ EGLSurface EGLAPIENTRY CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buf
} }
egl::Surface *surface = nullptr; egl::Surface *surface = nullptr;
error = display->createPbufferFromClientBuffer(configuration, buffer, attributes, &surface); error = display->createPbufferFromClientBuffer(configuration, buftype, buffer, attributes,
&surface);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); SetGlobalError(error);
......
...@@ -96,6 +96,7 @@ ...@@ -96,6 +96,7 @@
'angle_end2end_tests_win_sources': 'angle_end2end_tests_win_sources':
[ [
'<(angle_path)/src/tests/gl_tests/D3DImageFormatConversionTest.cpp', '<(angle_path)/src/tests/gl_tests/D3DImageFormatConversionTest.cpp',
'<(angle_path)/src/tests/gl_tests/D3DTextureTest.cpp',
'<(angle_path)/src/tests/gl_tests/D3D11EmulatedIndexedBufferTest.cpp', '<(angle_path)/src/tests/gl_tests/D3D11EmulatedIndexedBufferTest.cpp',
'<(angle_path)/src/tests/gl_tests/D3D11FormatTablesTest.cpp', '<(angle_path)/src/tests/gl_tests/D3D11FormatTablesTest.cpp',
'<(angle_path)/src/tests/gl_tests/D3D11InputLayoutCacheTest.cpp', '<(angle_path)/src/tests/gl_tests/D3D11InputLayoutCacheTest.cpp',
......
...@@ -103,9 +103,10 @@ class MockEGLFactory : public EGLImplFactory ...@@ -103,9 +103,10 @@ class MockEGLFactory : public EGLImplFactory
SurfaceImpl *(const egl::SurfaceState &, SurfaceImpl *(const egl::SurfaceState &,
const egl::Config *, const egl::Config *,
const egl::AttributeMap &)); const egl::AttributeMap &));
MOCK_METHOD4(createPbufferFromClientBuffer, MOCK_METHOD5(createPbufferFromClientBuffer,
SurfaceImpl *(const egl::SurfaceState &, SurfaceImpl *(const egl::SurfaceState &,
const egl::Config *, const egl::Config *,
EGLenum,
EGLClientBuffer, EGLClientBuffer,
const egl::AttributeMap &)); const egl::AttributeMap &));
MOCK_METHOD4(createPixmapSurface, MOCK_METHOD4(createPixmapSurface,
......
...@@ -549,6 +549,14 @@ bool ANGLETest::eglClientExtensionEnabled(const std::string &extName) ...@@ -549,6 +549,14 @@ bool ANGLETest::eglClientExtensionEnabled(const std::string &extName)
return checkExtensionExists(eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS), extName); return checkExtensionExists(eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS), extName);
} }
bool ANGLETest::eglDeviceExtensionEnabled(EGLDeviceEXT device, const std::string &extName)
{
PFNEGLQUERYDEVICESTRINGEXTPROC eglQueryDeviceStringEXT =
reinterpret_cast<PFNEGLQUERYDEVICESTRINGEXTPROC>(
eglGetProcAddress("eglQueryDeviceStringEXT"));
return checkExtensionExists(eglQueryDeviceStringEXT(device, EGL_EXTENSIONS), extName);
}
void ANGLETest::setWindowWidth(int width) void ANGLETest::setWindowWidth(int width)
{ {
mWidth = width; mWidth = width;
......
...@@ -172,6 +172,7 @@ class ANGLETest : public ::testing::TestWithParam<angle::PlatformParameters> ...@@ -172,6 +172,7 @@ class ANGLETest : public ::testing::TestWithParam<angle::PlatformParameters>
static GLuint compileShader(GLenum type, const std::string &source); static GLuint compileShader(GLenum type, const std::string &source);
static bool extensionEnabled(const std::string &extName); static bool extensionEnabled(const std::string &extName);
static bool eglClientExtensionEnabled(const std::string &extName); static bool eglClientExtensionEnabled(const std::string &extName);
static bool eglDeviceExtensionEnabled(EGLDeviceEXT device, const std::string &extName);
void setWindowWidth(int width); void setWindowWidth(int width);
void setWindowHeight(int height); void setWindowHeight(int height);
......
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