eglCreatePbufferFromClientBuffer implementation
Added support for eglCreatePbufferFromClientBuffer(), using an
IOSurface on MacOS, or just a straight buffer pointer on other
platforms.
Added new unit tests (IOSurfaceClientBufferTest class), which
pass on both Windows and MacOS.
Change-Id: I79a6b420d85fb1f3ae505e0c0067bad2e27510d4
Reviewed-on: https://swiftshader-review.googlesource.com/17168
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/OpenGL/libEGL/Surface.cpp b/src/OpenGL/libEGL/Surface.cpp
index d373990..ead75a6 100644
--- a/src/OpenGL/libEGL/Surface.cpp
+++ b/src/OpenGL/libEGL/Surface.cpp
@@ -63,6 +63,10 @@
swapBehavior = EGL_BUFFER_PRESERVED;
textureFormat = EGL_NO_TEXTURE;
textureTarget = EGL_NO_TEXTURE;
+ clientBufferFormat = EGL_NO_TEXTURE;
+ clientBufferType = EGL_NO_TEXTURE;
+ clientBuffer = nullptr;
+ clientBufferPlane = -1;
swapInterval = -1;
setSwapInterval(1);
}
@@ -78,7 +82,15 @@
if(libGLESv2)
{
- backBuffer = libGLESv2->createBackBuffer(width, height, config->mRenderTargetFormat, config->mSamples);
+ if(clientBuffer)
+ {
+ backBuffer = libGLESv2->createBackBufferFromClientBuffer(
+ egl::ClientBuffer(width, height, getClientBufferFormat(), clientBuffer, clientBufferPlane));
+ }
+ else
+ {
+ backBuffer = libGLESv2->createBackBuffer(width, height, config->mRenderTargetFormat, config->mSamples);
+ }
}
else if(libGLES_CM)
{
@@ -222,6 +234,51 @@
return largestPBuffer;
}
+sw::Format Surface::getClientBufferFormat() const
+{
+ switch(clientBufferType)
+ {
+ case GL_UNSIGNED_BYTE:
+ switch(clientBufferFormat)
+ {
+ case GL_RED:
+ return sw::FORMAT_R8;
+ case GL_RG:
+ return sw::FORMAT_G8R8;
+ case GL_BGRA_EXT:
+ return sw::FORMAT_A8R8G8B8;
+ default:
+ UNREACHABLE(clientBufferFormat);
+ break;
+ }
+ break;
+ case GL_UNSIGNED_SHORT:
+ switch(clientBufferFormat)
+ {
+ case GL_R16UI:
+ return sw::FORMAT_R16UI;
+ default:
+ UNREACHABLE(clientBufferFormat);
+ break;
+ }
+ break;
+ case GL_HALF_FLOAT:
+ switch(clientBufferFormat)
+ {
+ case GL_RGBA:
+ return sw::FORMAT_A16B16G16R16F;
+ default:
+ UNREACHABLE(clientBufferFormat);
+ break;
+ }
+ default:
+ UNREACHABLE(clientBufferType);
+ break;
+ }
+
+ return sw::FORMAT_NULL;
+}
+
void Surface::setBoundTexture(egl::Texture *texture)
{
this->texture = texture;
@@ -356,12 +413,21 @@
return Surface::initialize();
}
-PBufferSurface::PBufferSurface(Display *display, const Config *config, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureType, EGLBoolean largestPBuffer)
+PBufferSurface::PBufferSurface(Display *display, const Config *config, EGLint width, EGLint height,
+ EGLenum textureFormat, EGLenum textureTarget, EGLenum clientBufferFormat,
+ EGLenum clientBufferType, EGLBoolean largestPBuffer, EGLClientBuffer clientBuffer,
+ EGLint clientBufferPlane)
: Surface(display, config)
{
this->width = width;
this->height = height;
this->largestPBuffer = largestPBuffer;
+ this->textureFormat = textureFormat;
+ this->textureTarget = textureTarget;
+ this->clientBufferFormat = clientBufferFormat;
+ this->clientBufferType = clientBufferType;
+ this->clientBuffer = clientBuffer;
+ this->clientBufferPlane = clientBufferPlane;
}
PBufferSurface::~PBufferSurface()