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
Corentin Wallez
Geoff Lang
James Darpinian
Contacts
......@@ -20,8 +21,7 @@ Status
Draft
Version
Version 1, Dec 6, 2017
Version 2, Apr 1, 2019
Number
......@@ -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
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
There are no issues, please move on.
......@@ -120,3 +115,4 @@ Issues
Revision History
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,
if (drawSurface != nullptr)
{
SurfaceGL *glDrawSurface = GetImplAs<SurfaceGL>(drawSurface);
ANGLE_TRY(glDrawSurface->makeCurrent());
ANGLE_TRY(glDrawSurface->makeCurrent(context));
mCurrentDrawSurface = drawSurface;
return egl::NoError();
}
......
......@@ -27,7 +27,7 @@ class SurfaceGL : public SurfaceImpl
angle::Result initializeContents(const gl::Context *context,
const gl::ImageIndex &imageIndex) override;
virtual egl::Error makeCurrent() = 0;
virtual egl::Error makeCurrent(const gl::Context *context) = 0;
virtual egl::Error unMakeCurrent();
};
......
......@@ -38,7 +38,8 @@ class IOSurfaceSurfaceCGL : public SurfaceGL
~IOSurfaceSurfaceCGL() 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 postSubBuffer(const gl::Context *context,
......@@ -60,10 +61,13 @@ class IOSurfaceSurfaceCGL : public SurfaceGL
EGLint getSwapBehavior() const override;
static bool validateAttributes(EGLClientBuffer buffer, const egl::AttributeMap &attribs);
FramebufferImpl *createDefaultFramebuffer(const gl::Context *context,
const gl::FramebufferState &state) override;
private:
CGLContextObj mCGLContext;
IOSurfaceRef mIOSurface;
const gl::Context *mCurrentContext;
int mWidth;
int mHeight;
int mPlane;
......
......@@ -71,6 +71,7 @@ IOSurfaceSurfaceCGL::IOSurfaceSurfaceCGL(const egl::SurfaceState &state,
: SurfaceGL(state),
mCGLContext(cglContext),
mIOSurface(nullptr),
mCurrentContext(nullptr),
mWidth(0),
mHeight(0),
mPlane(0),
......@@ -105,15 +106,23 @@ egl::Error IOSurfaceSurfaceCGL::initialize(const egl::Display *display)
return egl::NoError();
}
egl::Error IOSurfaceSurfaceCGL::makeCurrent()
egl::Error IOSurfaceSurfaceCGL::makeCurrent(const gl::Context *context)
{
// Make current is not supported on IOSurface pbuffers.
return egl::EglBadSurface();
ASSERT(!mCurrentContext);
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)
{
UNREACHABLE();
return egl::NoError();
}
......@@ -235,4 +244,50 @@ bool IOSurfaceSurfaceCGL::validateAttributes(EGLClientBuffer buffer,
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
......@@ -30,7 +30,7 @@ class PbufferSurfaceCGL : public SurfaceGL
~PbufferSurfaceCGL() 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 postSubBuffer(const gl::Context *context,
......
......@@ -59,7 +59,7 @@ egl::Error PbufferSurfaceCGL::initialize(const egl::Display *display)
return egl::NoError();
}
egl::Error PbufferSurfaceCGL::makeCurrent()
egl::Error PbufferSurfaceCGL::makeCurrent(const gl::Context *context)
{
return egl::NoError();
}
......
......@@ -62,7 +62,7 @@ class WindowSurfaceCGL : public SurfaceGL
~WindowSurfaceCGL() 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 postSubBuffer(const gl::Context *context,
......
......@@ -217,7 +217,7 @@ egl::Error WindowSurfaceCGL::initialize(const egl::Display *display)
return egl::Error(EGL_SUCCESS);
}
egl::Error WindowSurfaceCGL::makeCurrent()
egl::Error WindowSurfaceCGL::makeCurrent(const gl::Context *context)
{
return egl::Error(EGL_SUCCESS);
}
......
......@@ -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
return egl::NoError();
......
......@@ -23,7 +23,7 @@ class SurfaceEGL : public SurfaceGL
SurfaceEGL(const egl::SurfaceState &state, const FunctionsEGL *egl, EGLConfig config);
~SurfaceEGL() override;
egl::Error makeCurrent() override;
egl::Error makeCurrent(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 postSubBuffer(const gl::Context *context,
......
......@@ -34,7 +34,7 @@ FramebufferImpl *SurfaceOzone::createDefaultFramebuffer(const gl::Context *conte
return mBuffer->framebufferGL(context, state);
}
egl::Error SurfaceOzone::makeCurrent()
egl::Error SurfaceOzone::makeCurrent(const gl::Context *context)
{
return egl::NoError();
}
......
......@@ -25,7 +25,7 @@ class SurfaceOzone : public SurfaceGL
const gl::FramebufferState &state) 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 postSubBuffer(const gl::Context *context,
......
......@@ -64,7 +64,7 @@ egl::Error PbufferSurfaceGLX::initialize(const egl::Display *display)
return egl::NoError();
}
egl::Error PbufferSurfaceGLX::makeCurrent()
egl::Error PbufferSurfaceGLX::makeCurrent(const gl::Context *context)
{
return egl::NoError();
}
......
......@@ -29,7 +29,7 @@ class PbufferSurfaceGLX : public SurfaceGLX
~PbufferSurfaceGLX() 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 postSubBuffer(const gl::Context *context,
......
......@@ -127,7 +127,7 @@ egl::Error WindowSurfaceGLX::initialize(const egl::Display *display)
return egl::NoError();
}
egl::Error WindowSurfaceGLX::makeCurrent()
egl::Error WindowSurfaceGLX::makeCurrent(const gl::Context *context)
{
return egl::NoError();
}
......
......@@ -31,7 +31,7 @@ class WindowSurfaceGLX : public SurfaceGLX
~WindowSurfaceGLX() 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 postSubBuffer(const gl::Context *context,
......
......@@ -348,7 +348,7 @@ egl::Error D3DTextureSurfaceWGL::initialize(const egl::Display *display)
return egl::NoError();
}
egl::Error D3DTextureSurfaceWGL::makeCurrent()
egl::Error D3DTextureSurfaceWGL::makeCurrent(const gl::Context *context)
{
if (!mFunctionsWGL->dxLockObjectsNV(mDeviceHandle, 1, &mBoundObjectRenderbufferHandle))
{
......
......@@ -41,7 +41,7 @@ class D3DTextureSurfaceWGL : public SurfaceWGL
ID3D11Device *d3d11Device);
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;
......
......@@ -112,7 +112,7 @@ egl::Error DXGISwapChainWindowSurfaceWGL::initialize(const egl::Display *display
return createSwapChain();
}
egl::Error DXGISwapChainWindowSurfaceWGL::makeCurrent()
egl::Error DXGISwapChainWindowSurfaceWGL::makeCurrent(const gl::Context *context)
{
return egl::NoError();
}
......
......@@ -38,7 +38,7 @@ class DXGISwapChainWindowSurfaceWGL : public SurfaceWGL
~DXGISwapChainWindowSurfaceWGL() 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 postSubBuffer(const gl::Context *context,
......
......@@ -122,7 +122,7 @@ egl::Error PbufferSurfaceWGL::initialize(const egl::Display *display)
return egl::NoError();
}
egl::Error PbufferSurfaceWGL::makeCurrent()
egl::Error PbufferSurfaceWGL::makeCurrent(const gl::Context *context)
{
return egl::NoError();
}
......
......@@ -33,7 +33,7 @@ class PbufferSurfaceWGL : public SurfaceWGL
~PbufferSurfaceWGL() 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 postSubBuffer(const gl::Context *context,
......
......@@ -92,7 +92,7 @@ egl::Error WindowSurfaceWGL::initialize(const egl::Display *display)
return egl::NoError();
}
egl::Error WindowSurfaceWGL::makeCurrent()
egl::Error WindowSurfaceWGL::makeCurrent(const gl::Context *context)
{
return egl::NoError();
}
......
......@@ -29,7 +29,7 @@ class WindowSurfaceWGL : public SurfaceWGL
~WindowSurfaceWGL() 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 postSubBuffer(const gl::Context *context,
......
......@@ -708,8 +708,8 @@ TEST_P(IOSurfaceClientBufferTest, NegativeValidationBadAttributes)
}
}
// Test IOSurface pbuffers cannot be made current
TEST_P(IOSurfaceClientBufferTest, MakeCurrentDisallowed)
// Test IOSurface pbuffers can be made current
TEST_P(IOSurfaceClientBufferTest, MakeCurrent)
{
ScopedIOSurfaceRef ioSurface = CreateSinglePlaneIOSurface(10, 10, 'BGRA', 4);
......@@ -718,8 +718,13 @@ TEST_P(IOSurfaceClientBufferTest, MakeCurrentDisallowed)
EGLContext context = getEGLWindow()->getContext();
EGLBoolean result = eglMakeCurrent(mDisplay, pbuffer, pbuffer, context);
EXPECT_EGL_FALSE(result);
EXPECT_EGL_ERROR(EGL_BAD_SURFACE);
EXPECT_EGL_TRUE(result);
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
......
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