Commit 4e297707 by jbauman@chromium.org

Add support for eglCreatePbufferFromClientBuffer, taking as input a D3D share…

Add support for eglCreatePbufferFromClientBuffer, taking as input a D3D share handle corresponding to the enum EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE. No spec as of yet, but it does the obvious thing. BUG=129 TEST= Review URL: http://codereview.appspot.com/4325048 git-svn-id: https://angleproject.googlecode.com/svn/trunk@650 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent f1f28c80
Name
ANGLE_d3d_share_handle_client_buffer
Name Strings
EGL_ANGLE_d3d_share_handle_client_buffer
Contributors
John Bauman
Alastair Patrick
Daniel Koch
Contacts
John Bauman, Google Inc. (jbauman 'at' chromium.org)
Status
Complete
Implemented (ANGLE r650)
Version
Version 3, May 12, 2011
Number
EGL Extension #??
Dependencies
Requires the EGL_ANGLE_surface_d3d_texture_2d_share_handle extension.
This extension is written against the wording of the EGL 1.4
Specification.
Overview
This extension allows creating EGL surfaces from handles to textures
shared from the Direct3D API or from
EGL_ANGLE_surface_texture_2d_share_handle.
New Types
None
New Procedures and Functions
None
New Tokens
Accepted in the <buftype> parameter of eglCreatePbufferFromClientBuffer:
EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200
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 share handles."
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, the width and height of the pbuffer
are determined by the width and height of <buffer>. When <buftype> is
EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE, the width and height are specified
using EGL_WIDTH and EGL_HEIGHT, or else they default to zero. The width
and height must match the dimensions of the texture which the share handle
was created from or else an EGL_BAD_ALLOC error is generated."
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_2D_SHARE_HANDLE_ANGLE".
Append the following text to the fourth paragraph of Section 3.5.3.
"When <buftype> is EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE, <buffer> must be
a valid D3D share handle, cast into the type EGLClientBuffer. The handle
may be obtained from the Direct3D9Ex CreateTexture function, from DXGI's
GetSharedHandle method on an ID3D10Texture2D, or from the
EGL_ANGLE_surface_d3d_texture_2d_share_handle extension."
Issues
Revision History
Version 3, 2011/05/12
- publish
Version 2, 2011/05/03
- specify EGL_D3D_TEXTURE_2D_SHARE_HANDLE
- specify error if dimensions don't match
Version 1, 2011/04/12 - first draft.
#define MAJOR_VERSION 0 #define MAJOR_VERSION 0
#define MINOR_VERSION 0 #define MINOR_VERSION 0
#define BUILD_VERSION 0 #define BUILD_VERSION 0
#define BUILD_REVISION 649 #define BUILD_REVISION 650
#define STRINGIFY(x) #x #define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x) #define MACRO_STRINGIFY(x) STRINGIFY(x)
......
...@@ -451,12 +451,19 @@ EGLSurface Display::createWindowSurface(HWND window, EGLConfig config, const EGL ...@@ -451,12 +451,19 @@ EGLSurface Display::createWindowSurface(HWND window, EGLConfig config, const EGL
} }
Surface *surface = new Surface(this, configuration, window); Surface *surface = new Surface(this, configuration, window);
if (!surface->initialize())
{
delete surface;
return EGL_NO_SURFACE;
}
mSurfaceSet.insert(surface); mSurfaceSet.insert(surface);
return success(surface); return success(surface);
} }
EGLSurface Display::createOffscreenSurface(EGLConfig config, const EGLint *attribList) EGLSurface Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList)
{ {
EGLint width = 0, height = 0; EGLint width = 0, height = 0;
EGLenum textureFormat = EGL_NO_TEXTURE; EGLenum textureFormat = EGL_NO_TEXTURE;
...@@ -550,7 +557,14 @@ EGLSurface Display::createOffscreenSurface(EGLConfig config, const EGLint *attri ...@@ -550,7 +557,14 @@ EGLSurface Display::createOffscreenSurface(EGLConfig config, const EGLint *attri
return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
} }
Surface *surface = new Surface(this, configuration, width, height, textureFormat, textureTarget); Surface *surface = new Surface(this, configuration, shareHandle, width, height, textureFormat, textureTarget);
if (!surface->initialize())
{
delete surface;
return EGL_NO_SURFACE;
}
mSurfaceSet.insert(surface); mSurfaceSet.insert(surface);
return success(surface); return success(surface);
......
...@@ -43,7 +43,7 @@ class Display ...@@ -43,7 +43,7 @@ class Display
bool getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value); bool getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value);
EGLSurface createWindowSurface(HWND window, EGLConfig config, const EGLint *attribList); EGLSurface createWindowSurface(HWND window, EGLConfig config, const EGLint *attribList);
EGLSurface createOffscreenSurface(EGLConfig config, const EGLint *attribList); EGLSurface createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList);
EGLContext createContext(EGLConfig configHandle, const gl::Context *shareContext); EGLContext createContext(EGLConfig configHandle, const gl::Context *shareContext);
void destroySurface(egl::Surface *surface); void destroySurface(egl::Surface *surface);
......
...@@ -41,17 +41,15 @@ Surface::Surface(Display *display, const Config *config, HWND window) ...@@ -41,17 +41,15 @@ Surface::Surface(Display *display, const Config *config, HWND window)
mIsPendingDestroy = false; mIsPendingDestroy = false;
subclassWindow(); subclassWindow();
resetSwapChain();
} }
Surface::Surface(Display *display, const Config *config, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureType) Surface::Surface(Display *display, const Config *config, HANDLE shareHandle, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureType)
: mDisplay(display), mWindow(NULL), mConfig(config), mWidth(width), mHeight(height) : mDisplay(display), mWindow(NULL), mConfig(config), mShareHandle(shareHandle), mWidth(width), mHeight(height)
{ {
mSwapChain = NULL; mSwapChain = NULL;
mDepthStencil = NULL; mDepthStencil = NULL;
mRenderTarget = NULL; mRenderTarget = NULL;
mOffscreenTexture = NULL; mOffscreenTexture = NULL;
mShareHandle = NULL;
mWindowSubclassed = false; mWindowSubclassed = false;
mTexture = NULL; mTexture = NULL;
mTextureFormat = textureFormat; mTextureFormat = textureFormat;
...@@ -64,8 +62,6 @@ Surface::Surface(Display *display, const Config *config, EGLint width, EGLint he ...@@ -64,8 +62,6 @@ Surface::Surface(Display *display, const Config *config, EGLint width, EGLint he
setSwapInterval(1); setSwapInterval(1);
mIsPendingDestroy = false; mIsPendingDestroy = false;
resetSwapChain(width, height);
} }
Surface::~Surface() Surface::~Surface()
...@@ -74,6 +70,12 @@ Surface::~Surface() ...@@ -74,6 +70,12 @@ Surface::~Surface()
release(); release();
} }
bool Surface::initialize()
{
ASSERT(!mSwapChain && !mOffscreenTexture && !mDepthStencil);
return resetSwapChain();
}
void Surface::release() void Surface::release()
{ {
if (mSwapChain) if (mSwapChain)
...@@ -107,11 +109,11 @@ void Surface::release() ...@@ -107,11 +109,11 @@ void Surface::release()
} }
} }
void Surface::resetSwapChain() bool Surface::resetSwapChain()
{ {
if (!mWindow) { if (!mWindow)
resetSwapChain(mWidth, mHeight); {
return; return resetSwapChain(mWidth, mHeight);
} }
RECT windowRect; RECT windowRect;
...@@ -120,19 +122,19 @@ void Surface::resetSwapChain() ...@@ -120,19 +122,19 @@ void Surface::resetSwapChain()
ASSERT(false); ASSERT(false);
ERR("Could not retrieve the window dimensions"); ERR("Could not retrieve the window dimensions");
return; return false;
} }
resetSwapChain(windowRect.right - windowRect.left, windowRect.bottom - windowRect.top); return resetSwapChain(windowRect.right - windowRect.left, windowRect.bottom - windowRect.top);
} }
void Surface::resetSwapChain(int backbufferWidth, int backbufferHeight) bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
{ {
IDirect3DDevice9 *device = mDisplay->getDevice(); IDirect3DDevice9 *device = mDisplay->getDevice();
if (device == NULL) if (device == NULL)
{ {
return; return false;
} }
// Evict all non-render target textures to system memory and release all resources // Evict all non-render target textures to system memory and release all resources
...@@ -176,7 +178,7 @@ void Surface::resetSwapChain(int backbufferWidth, int backbufferHeight) ...@@ -176,7 +178,7 @@ void Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result); ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result);
release(); release();
return error(EGL_BAD_ALLOC); return error(false, EGL_BAD_ALLOC);
} }
if (mConfig->mDepthStencilFormat != D3DFMT_UNKNOWN) if (mConfig->mDepthStencilFormat != D3DFMT_UNKNOWN)
...@@ -192,7 +194,7 @@ void Surface::resetSwapChain(int backbufferWidth, int backbufferHeight) ...@@ -192,7 +194,7 @@ void Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
ERR("Could not create depthstencil surface for new swap chain: %08lX", result); ERR("Could not create depthstencil surface for new swap chain: %08lX", result);
release(); release();
return error(EGL_BAD_ALLOC); return error(false, EGL_BAD_ALLOC);
} }
if (mWindow) { if (mWindow) {
...@@ -206,6 +208,7 @@ void Surface::resetSwapChain(int backbufferWidth, int backbufferHeight) ...@@ -206,6 +208,7 @@ void Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
mHeight = presentParameters.BackBufferHeight; mHeight = presentParameters.BackBufferHeight;
mPresentIntervalDirty = false; mPresentIntervalDirty = false;
return true;
} }
HWND Surface::getWindowHandle() HWND Surface::getWindowHandle()
......
...@@ -31,12 +31,13 @@ class Surface ...@@ -31,12 +31,13 @@ class Surface
{ {
public: public:
Surface(Display *display, const egl::Config *config, HWND window); Surface(Display *display, const egl::Config *config, HWND window);
Surface(Display *display, const egl::Config *config, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureTarget); Surface(Display *display, const egl::Config *config, HANDLE shareHandle, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureTarget);
~Surface(); ~Surface();
bool initialize();
void release(); void release();
void resetSwapChain(); bool resetSwapChain();
HWND getWindowHandle(); HWND getWindowHandle();
bool swap(); bool swap();
...@@ -77,7 +78,7 @@ private: ...@@ -77,7 +78,7 @@ private:
void subclassWindow(); void subclassWindow();
void unsubclassWindow(); void unsubclassWindow();
void resetSwapChain(int backbufferWidth, int backbufferHeight); bool resetSwapChain(int backbufferWidth, int backbufferHeight);
static DWORD convertInterval(EGLint interval); static DWORD convertInterval(EGLint interval);
const HWND mWindow; // Window that the surface is created for. const HWND mWindow; // Window that the surface is created for.
......
...@@ -362,7 +362,7 @@ EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, c ...@@ -362,7 +362,7 @@ EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, c
return EGL_NO_SURFACE; return EGL_NO_SURFACE;
} }
return display->createOffscreenSurface(config, attrib_list); return display->createOffscreenSurface(config, NULL, attrib_list);
} }
catch(std::bad_alloc&) catch(std::bad_alloc&)
{ {
...@@ -650,9 +650,12 @@ EGLSurface __stdcall eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum bu ...@@ -650,9 +650,12 @@ EGLSurface __stdcall eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum bu
return EGL_NO_SURFACE; return EGL_NO_SURFACE;
} }
UNIMPLEMENTED(); // FIXME if (buftype != EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE || !buffer)
{
return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
}
return success(EGL_NO_SURFACE); return display->createOffscreenSurface(config, (HANDLE)buffer, attrib_list);
} }
catch(std::bad_alloc&) catch(std::bad_alloc&)
{ {
......
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