Commit 2889dff6 by James Darpinian Committed by Commit Bot

Mac: Support using an IOSurface as the default framebuffer

Bug: angleproject:2764 Change-Id: I3fdab330b59ed996f68e3063debca29323a66cf0 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1542599 Commit-Queue: James Darpinian <jdarpinian@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 892d1805
...@@ -10,6 +10,7 @@ Contributors ...@@ -10,6 +10,7 @@ Contributors
Corentin Wallez Corentin Wallez
Geoff Lang Geoff Lang
James Darpinian
Contacts Contacts
...@@ -20,8 +21,7 @@ Status ...@@ -20,8 +21,7 @@ Status
Draft Draft
Version Version
Version 2, Apr 1, 2019
Version 1, Dec 6, 2017
Number Number
...@@ -108,11 +108,6 @@ Additions to Chapter 3 of the EGL 1.4 Specification (EGL Functions and Errors) ...@@ -108,11 +108,6 @@ Additions to Chapter 3 of the EGL 1.4 Specification (EGL Functions and Errors)
of the associcated IOSurface object are undefined while the pbuffer is of the associcated IOSurface object are undefined while the pbuffer is
bound to a client texture." bound to a client texture."
Append to the list of errors generated by eglMakeCurrent in Section 3.7.3:
" - If either draw or read are pbuffers created with
eglCreatePbufferFromClientBuffer with <buftype> set to EGL_IOSURFACE_ANGLE,
an EGL_BAD_SURFACE is generated."
Issues Issues
There are no issues, please move on. There are no issues, please move on.
...@@ -120,3 +115,4 @@ Issues ...@@ -120,3 +115,4 @@ Issues
Revision History Revision History
Version 1, 2017/12/06 - first draft. Version 1, 2017/12/06 - first draft.
Version 2, 2019/04/01 - Allow MakeCurrent.
...@@ -76,7 +76,7 @@ egl::Error DisplayGL::makeCurrent(egl::Surface *drawSurface, ...@@ -76,7 +76,7 @@ egl::Error DisplayGL::makeCurrent(egl::Surface *drawSurface,
if (drawSurface != nullptr) if (drawSurface != nullptr)
{ {
SurfaceGL *glDrawSurface = GetImplAs<SurfaceGL>(drawSurface); SurfaceGL *glDrawSurface = GetImplAs<SurfaceGL>(drawSurface);
ANGLE_TRY(glDrawSurface->makeCurrent()); ANGLE_TRY(glDrawSurface->makeCurrent(context));
mCurrentDrawSurface = drawSurface; mCurrentDrawSurface = drawSurface;
return egl::NoError(); return egl::NoError();
} }
......
...@@ -27,7 +27,7 @@ class SurfaceGL : public SurfaceImpl ...@@ -27,7 +27,7 @@ class SurfaceGL : public SurfaceImpl
angle::Result initializeContents(const gl::Context *context, angle::Result initializeContents(const gl::Context *context,
const gl::ImageIndex &imageIndex) override; const gl::ImageIndex &imageIndex) override;
virtual egl::Error makeCurrent() = 0; virtual egl::Error makeCurrent(const gl::Context *context) = 0;
virtual egl::Error unMakeCurrent(); virtual egl::Error unMakeCurrent();
}; };
......
...@@ -38,7 +38,8 @@ class IOSurfaceSurfaceCGL : public SurfaceGL ...@@ -38,7 +38,8 @@ class IOSurfaceSurfaceCGL : public SurfaceGL
~IOSurfaceSurfaceCGL() override; ~IOSurfaceSurfaceCGL() override;
egl::Error initialize(const egl::Display *display) override; egl::Error initialize(const egl::Display *display) override;
egl::Error makeCurrent() override; egl::Error makeCurrent(const gl::Context *context) override;
egl::Error unMakeCurrent() override;
egl::Error swap(const gl::Context *context) override; egl::Error swap(const gl::Context *context) override;
egl::Error postSubBuffer(const gl::Context *context, egl::Error postSubBuffer(const gl::Context *context,
...@@ -60,10 +61,13 @@ class IOSurfaceSurfaceCGL : public SurfaceGL ...@@ -60,10 +61,13 @@ class IOSurfaceSurfaceCGL : public SurfaceGL
EGLint getSwapBehavior() const override; EGLint getSwapBehavior() const override;
static bool validateAttributes(EGLClientBuffer buffer, const egl::AttributeMap &attribs); static bool validateAttributes(EGLClientBuffer buffer, const egl::AttributeMap &attribs);
FramebufferImpl *createDefaultFramebuffer(const gl::Context *context,
const gl::FramebufferState &state) override;
private: private:
CGLContextObj mCGLContext; CGLContextObj mCGLContext;
IOSurfaceRef mIOSurface; IOSurfaceRef mIOSurface;
const gl::Context *mCurrentContext;
int mWidth; int mWidth;
int mHeight; int mHeight;
int mPlane; int mPlane;
......
...@@ -71,6 +71,7 @@ IOSurfaceSurfaceCGL::IOSurfaceSurfaceCGL(const egl::SurfaceState &state, ...@@ -71,6 +71,7 @@ IOSurfaceSurfaceCGL::IOSurfaceSurfaceCGL(const egl::SurfaceState &state,
: SurfaceGL(state), : SurfaceGL(state),
mCGLContext(cglContext), mCGLContext(cglContext),
mIOSurface(nullptr), mIOSurface(nullptr),
mCurrentContext(nullptr),
mWidth(0), mWidth(0),
mHeight(0), mHeight(0),
mPlane(0), mPlane(0),
...@@ -105,15 +106,23 @@ egl::Error IOSurfaceSurfaceCGL::initialize(const egl::Display *display) ...@@ -105,15 +106,23 @@ egl::Error IOSurfaceSurfaceCGL::initialize(const egl::Display *display)
return egl::NoError(); return egl::NoError();
} }
egl::Error IOSurfaceSurfaceCGL::makeCurrent() egl::Error IOSurfaceSurfaceCGL::makeCurrent(const gl::Context *context)
{ {
// Make current is not supported on IOSurface pbuffers. ASSERT(!mCurrentContext);
return egl::EglBadSurface(); mCurrentContext = context;
return egl::NoError();
}
egl::Error IOSurfaceSurfaceCGL::unMakeCurrent()
{
ASSERT(mCurrentContext);
GetFunctionsGL(mCurrentContext)->flush();
mCurrentContext = nullptr;
return egl::NoError();
} }
egl::Error IOSurfaceSurfaceCGL::swap(const gl::Context *context) egl::Error IOSurfaceSurfaceCGL::swap(const gl::Context *context)
{ {
UNREACHABLE();
return egl::NoError(); return egl::NoError();
} }
...@@ -235,4 +244,50 @@ bool IOSurfaceSurfaceCGL::validateAttributes(EGLClientBuffer buffer, ...@@ -235,4 +244,50 @@ bool IOSurfaceSurfaceCGL::validateAttributes(EGLClientBuffer buffer,
return true; return true;
} }
// Wraps a FramebufferGL to hook the destroy function to delete the texture associated with the
// framebuffer.
class IOSurfaceFramebuffer : public FramebufferGL
{
public:
IOSurfaceFramebuffer(const gl::FramebufferState &data,
GLuint id,
GLuint textureId,
bool isDefault)
: FramebufferGL(data, id, isDefault), mTextureId(textureId)
{}
void destroy(const gl::Context *context) override
{
GetFunctionsGL(context)->deleteTextures(1, &mTextureId);
FramebufferGL::destroy(context);
}
private:
GLuint mTextureId;
};
FramebufferImpl *IOSurfaceSurfaceCGL::createDefaultFramebuffer(const gl::Context *context,
const gl::FramebufferState &state)
{
const FunctionsGL *functions = GetFunctionsGL(context);
StateManagerGL *stateManager = GetStateManagerGL(context);
GLuint texture = 0;
functions->genTextures(1, &texture);
const auto &format = kIOSurfaceFormats[mFormatIndex];
stateManager->bindTexture(gl::TextureType::Rectangle, texture);
CGLError error = CGLTexImageIOSurface2D(mCGLContext, GL_TEXTURE_RECTANGLE, format.nativeFormat,
mWidth, mHeight, format.nativeInternalFormat,
format.nativeType, mIOSurface, mPlane);
ASSERT(error == kCGLNoError);
GLuint framebuffer = 0;
functions->genFramebuffers(1, &framebuffer);
stateManager->bindFramebuffer(GL_FRAMEBUFFER, framebuffer);
stateManager->bindTexture(gl::TextureType::Rectangle, texture);
functions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE,
texture, 0);
return new IOSurfaceFramebuffer(state, framebuffer, texture, true);
}
} // namespace rx } // namespace rx
...@@ -30,7 +30,7 @@ class PbufferSurfaceCGL : public SurfaceGL ...@@ -30,7 +30,7 @@ class PbufferSurfaceCGL : public SurfaceGL
~PbufferSurfaceCGL() override; ~PbufferSurfaceCGL() override;
egl::Error initialize(const egl::Display *display) override; egl::Error initialize(const egl::Display *display) override;
egl::Error makeCurrent() override; egl::Error makeCurrent(const gl::Context *context) override;
egl::Error swap(const gl::Context *context) override; egl::Error swap(const gl::Context *context) override;
egl::Error postSubBuffer(const gl::Context *context, egl::Error postSubBuffer(const gl::Context *context,
......
...@@ -59,7 +59,7 @@ egl::Error PbufferSurfaceCGL::initialize(const egl::Display *display) ...@@ -59,7 +59,7 @@ egl::Error PbufferSurfaceCGL::initialize(const egl::Display *display)
return egl::NoError(); return egl::NoError();
} }
egl::Error PbufferSurfaceCGL::makeCurrent() egl::Error PbufferSurfaceCGL::makeCurrent(const gl::Context *context)
{ {
return egl::NoError(); return egl::NoError();
} }
......
...@@ -62,7 +62,7 @@ class WindowSurfaceCGL : public SurfaceGL ...@@ -62,7 +62,7 @@ class WindowSurfaceCGL : public SurfaceGL
~WindowSurfaceCGL() override; ~WindowSurfaceCGL() override;
egl::Error initialize(const egl::Display *display) override; egl::Error initialize(const egl::Display *display) override;
egl::Error makeCurrent() override; egl::Error makeCurrent(const gl::Context *context) override;
egl::Error swap(const gl::Context *context) override; egl::Error swap(const gl::Context *context) override;
egl::Error postSubBuffer(const gl::Context *context, egl::Error postSubBuffer(const gl::Context *context,
......
...@@ -217,7 +217,7 @@ egl::Error WindowSurfaceCGL::initialize(const egl::Display *display) ...@@ -217,7 +217,7 @@ egl::Error WindowSurfaceCGL::initialize(const egl::Display *display)
return egl::Error(EGL_SUCCESS); return egl::Error(EGL_SUCCESS);
} }
egl::Error WindowSurfaceCGL::makeCurrent() egl::Error WindowSurfaceCGL::makeCurrent(const gl::Context *context)
{ {
return egl::Error(EGL_SUCCESS); return egl::Error(EGL_SUCCESS);
} }
......
...@@ -30,7 +30,7 @@ SurfaceEGL::~SurfaceEGL() ...@@ -30,7 +30,7 @@ SurfaceEGL::~SurfaceEGL()
} }
} }
egl::Error SurfaceEGL::makeCurrent() egl::Error SurfaceEGL::makeCurrent(const gl::Context *context)
{ {
// Handling of makeCurrent is done in DisplayEGL // Handling of makeCurrent is done in DisplayEGL
return egl::NoError(); return egl::NoError();
......
...@@ -23,7 +23,7 @@ class SurfaceEGL : public SurfaceGL ...@@ -23,7 +23,7 @@ class SurfaceEGL : public SurfaceGL
SurfaceEGL(const egl::SurfaceState &state, const FunctionsEGL *egl, EGLConfig config); SurfaceEGL(const egl::SurfaceState &state, const FunctionsEGL *egl, EGLConfig config);
~SurfaceEGL() override; ~SurfaceEGL() override;
egl::Error makeCurrent() override; egl::Error makeCurrent(const gl::Context *context) override;
egl::Error swap(const gl::Context *context) override; egl::Error swap(const gl::Context *context) override;
egl::Error swapWithDamage(const gl::Context *context, EGLint *rects, EGLint n_rects) override; egl::Error swapWithDamage(const gl::Context *context, EGLint *rects, EGLint n_rects) override;
egl::Error postSubBuffer(const gl::Context *context, egl::Error postSubBuffer(const gl::Context *context,
......
...@@ -34,7 +34,7 @@ FramebufferImpl *SurfaceOzone::createDefaultFramebuffer(const gl::Context *conte ...@@ -34,7 +34,7 @@ FramebufferImpl *SurfaceOzone::createDefaultFramebuffer(const gl::Context *conte
return mBuffer->framebufferGL(context, state); return mBuffer->framebufferGL(context, state);
} }
egl::Error SurfaceOzone::makeCurrent() egl::Error SurfaceOzone::makeCurrent(const gl::Context *context)
{ {
return egl::NoError(); return egl::NoError();
} }
......
...@@ -25,7 +25,7 @@ class SurfaceOzone : public SurfaceGL ...@@ -25,7 +25,7 @@ class SurfaceOzone : public SurfaceGL
const gl::FramebufferState &state) override; const gl::FramebufferState &state) override;
egl::Error initialize(const egl::Display *display) override; egl::Error initialize(const egl::Display *display) override;
egl::Error makeCurrent() override; egl::Error makeCurrent(const gl::Context *context) override;
egl::Error swap(const gl::Context *context) override; egl::Error swap(const gl::Context *context) override;
egl::Error postSubBuffer(const gl::Context *context, egl::Error postSubBuffer(const gl::Context *context,
......
...@@ -64,7 +64,7 @@ egl::Error PbufferSurfaceGLX::initialize(const egl::Display *display) ...@@ -64,7 +64,7 @@ egl::Error PbufferSurfaceGLX::initialize(const egl::Display *display)
return egl::NoError(); return egl::NoError();
} }
egl::Error PbufferSurfaceGLX::makeCurrent() egl::Error PbufferSurfaceGLX::makeCurrent(const gl::Context *context)
{ {
return egl::NoError(); return egl::NoError();
} }
......
...@@ -29,7 +29,7 @@ class PbufferSurfaceGLX : public SurfaceGLX ...@@ -29,7 +29,7 @@ class PbufferSurfaceGLX : public SurfaceGLX
~PbufferSurfaceGLX() override; ~PbufferSurfaceGLX() override;
egl::Error initialize(const egl::Display *display) override; egl::Error initialize(const egl::Display *display) override;
egl::Error makeCurrent() override; egl::Error makeCurrent(const gl::Context *context) override;
egl::Error swap(const gl::Context *context) override; egl::Error swap(const gl::Context *context) override;
egl::Error postSubBuffer(const gl::Context *context, egl::Error postSubBuffer(const gl::Context *context,
......
...@@ -127,7 +127,7 @@ egl::Error WindowSurfaceGLX::initialize(const egl::Display *display) ...@@ -127,7 +127,7 @@ egl::Error WindowSurfaceGLX::initialize(const egl::Display *display)
return egl::NoError(); return egl::NoError();
} }
egl::Error WindowSurfaceGLX::makeCurrent() egl::Error WindowSurfaceGLX::makeCurrent(const gl::Context *context)
{ {
return egl::NoError(); return egl::NoError();
} }
......
...@@ -31,7 +31,7 @@ class WindowSurfaceGLX : public SurfaceGLX ...@@ -31,7 +31,7 @@ class WindowSurfaceGLX : public SurfaceGLX
~WindowSurfaceGLX() override; ~WindowSurfaceGLX() override;
egl::Error initialize(const egl::Display *display) override; egl::Error initialize(const egl::Display *display) override;
egl::Error makeCurrent() override; egl::Error makeCurrent(const gl::Context *context) override;
egl::Error swap(const gl::Context *context) override; egl::Error swap(const gl::Context *context) override;
egl::Error postSubBuffer(const gl::Context *context, egl::Error postSubBuffer(const gl::Context *context,
......
...@@ -348,7 +348,7 @@ egl::Error D3DTextureSurfaceWGL::initialize(const egl::Display *display) ...@@ -348,7 +348,7 @@ egl::Error D3DTextureSurfaceWGL::initialize(const egl::Display *display)
return egl::NoError(); return egl::NoError();
} }
egl::Error D3DTextureSurfaceWGL::makeCurrent() egl::Error D3DTextureSurfaceWGL::makeCurrent(const gl::Context *context)
{ {
if (!mFunctionsWGL->dxLockObjectsNV(mDeviceHandle, 1, &mBoundObjectRenderbufferHandle)) if (!mFunctionsWGL->dxLockObjectsNV(mDeviceHandle, 1, &mBoundObjectRenderbufferHandle))
{ {
......
...@@ -41,7 +41,7 @@ class D3DTextureSurfaceWGL : public SurfaceWGL ...@@ -41,7 +41,7 @@ class D3DTextureSurfaceWGL : public SurfaceWGL
ID3D11Device *d3d11Device); ID3D11Device *d3d11Device);
egl::Error initialize(const egl::Display *display) override; egl::Error initialize(const egl::Display *display) override;
egl::Error makeCurrent() override; egl::Error makeCurrent(const gl::Context *context) override;
egl::Error unMakeCurrent() override; egl::Error unMakeCurrent() override;
egl::Error swap(const gl::Context *context) override; egl::Error swap(const gl::Context *context) override;
......
...@@ -112,7 +112,7 @@ egl::Error DXGISwapChainWindowSurfaceWGL::initialize(const egl::Display *display ...@@ -112,7 +112,7 @@ egl::Error DXGISwapChainWindowSurfaceWGL::initialize(const egl::Display *display
return createSwapChain(); return createSwapChain();
} }
egl::Error DXGISwapChainWindowSurfaceWGL::makeCurrent() egl::Error DXGISwapChainWindowSurfaceWGL::makeCurrent(const gl::Context *context)
{ {
return egl::NoError(); return egl::NoError();
} }
......
...@@ -38,7 +38,7 @@ class DXGISwapChainWindowSurfaceWGL : public SurfaceWGL ...@@ -38,7 +38,7 @@ class DXGISwapChainWindowSurfaceWGL : public SurfaceWGL
~DXGISwapChainWindowSurfaceWGL() override; ~DXGISwapChainWindowSurfaceWGL() override;
egl::Error initialize(const egl::Display *display) override; egl::Error initialize(const egl::Display *display) override;
egl::Error makeCurrent() override; egl::Error makeCurrent(const gl::Context *context) override;
egl::Error swap(const gl::Context *context) override; egl::Error swap(const gl::Context *context) override;
egl::Error postSubBuffer(const gl::Context *context, egl::Error postSubBuffer(const gl::Context *context,
......
...@@ -122,7 +122,7 @@ egl::Error PbufferSurfaceWGL::initialize(const egl::Display *display) ...@@ -122,7 +122,7 @@ egl::Error PbufferSurfaceWGL::initialize(const egl::Display *display)
return egl::NoError(); return egl::NoError();
} }
egl::Error PbufferSurfaceWGL::makeCurrent() egl::Error PbufferSurfaceWGL::makeCurrent(const gl::Context *context)
{ {
return egl::NoError(); return egl::NoError();
} }
......
...@@ -33,7 +33,7 @@ class PbufferSurfaceWGL : public SurfaceWGL ...@@ -33,7 +33,7 @@ class PbufferSurfaceWGL : public SurfaceWGL
~PbufferSurfaceWGL() override; ~PbufferSurfaceWGL() override;
egl::Error initialize(const egl::Display *display) override; egl::Error initialize(const egl::Display *display) override;
egl::Error makeCurrent() override; egl::Error makeCurrent(const gl::Context *context) override;
egl::Error swap(const gl::Context *context) override; egl::Error swap(const gl::Context *context) override;
egl::Error postSubBuffer(const gl::Context *context, egl::Error postSubBuffer(const gl::Context *context,
......
...@@ -92,7 +92,7 @@ egl::Error WindowSurfaceWGL::initialize(const egl::Display *display) ...@@ -92,7 +92,7 @@ egl::Error WindowSurfaceWGL::initialize(const egl::Display *display)
return egl::NoError(); return egl::NoError();
} }
egl::Error WindowSurfaceWGL::makeCurrent() egl::Error WindowSurfaceWGL::makeCurrent(const gl::Context *context)
{ {
return egl::NoError(); return egl::NoError();
} }
......
...@@ -29,7 +29,7 @@ class WindowSurfaceWGL : public SurfaceWGL ...@@ -29,7 +29,7 @@ class WindowSurfaceWGL : public SurfaceWGL
~WindowSurfaceWGL() override; ~WindowSurfaceWGL() override;
egl::Error initialize(const egl::Display *display) override; egl::Error initialize(const egl::Display *display) override;
egl::Error makeCurrent() override; egl::Error makeCurrent(const gl::Context *context) override;
egl::Error swap(const gl::Context *context) override; egl::Error swap(const gl::Context *context) override;
egl::Error postSubBuffer(const gl::Context *context, egl::Error postSubBuffer(const gl::Context *context,
......
...@@ -708,8 +708,8 @@ TEST_P(IOSurfaceClientBufferTest, NegativeValidationBadAttributes) ...@@ -708,8 +708,8 @@ TEST_P(IOSurfaceClientBufferTest, NegativeValidationBadAttributes)
} }
} }
// Test IOSurface pbuffers cannot be made current // Test IOSurface pbuffers can be made current
TEST_P(IOSurfaceClientBufferTest, MakeCurrentDisallowed) TEST_P(IOSurfaceClientBufferTest, MakeCurrent)
{ {
ScopedIOSurfaceRef ioSurface = CreateSinglePlaneIOSurface(10, 10, 'BGRA', 4); ScopedIOSurfaceRef ioSurface = CreateSinglePlaneIOSurface(10, 10, 'BGRA', 4);
...@@ -718,8 +718,13 @@ TEST_P(IOSurfaceClientBufferTest, MakeCurrentDisallowed) ...@@ -718,8 +718,13 @@ TEST_P(IOSurfaceClientBufferTest, MakeCurrentDisallowed)
EGLContext context = getEGLWindow()->getContext(); EGLContext context = getEGLWindow()->getContext();
EGLBoolean result = eglMakeCurrent(mDisplay, pbuffer, pbuffer, context); EGLBoolean result = eglMakeCurrent(mDisplay, pbuffer, pbuffer, context);
EXPECT_EGL_FALSE(result); EXPECT_EGL_TRUE(result);
EXPECT_EGL_ERROR(EGL_BAD_SURFACE); EXPECT_EGL_SUCCESS();
// The test harness expects the EGL state to be restored before the test exits.
result = eglMakeCurrent(mDisplay, getEGLWindow()->getSurface(), getEGLWindow()->getSurface(),
context);
EXPECT_EGL_TRUE(result);
EXPECT_EGL_SUCCESS();
} }
// TODO(cwallez@chromium.org): Test setting width and height to less than the IOSurface's work as // TODO(cwallez@chromium.org): Test setting width and height to less than the IOSurface's work as
......
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