Implementation of EGL_KHR_fence_sync.
Bug 21662268
Change-Id: Iefdc18303c42967ccc25fd6580851e05520dc2b9
Reviewed-on: https://swiftshader-review.googlesource.com/4071
Tested-by: Nicolas Capens <capn@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/OpenGL/libEGL/Context.hpp b/src/OpenGL/libEGL/Context.hpp
index a19f983..35d948a 100644
--- a/src/OpenGL/libEGL/Context.hpp
+++ b/src/OpenGL/libEGL/Context.hpp
@@ -19,6 +19,7 @@
virtual EGLenum validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel) = 0;
virtual Image *createSharedImage(EGLenum target, GLuint name, GLuint textureLevel) = 0;
virtual int getClientVersion() const = 0;
+ virtual void finish() = 0;
protected:
virtual ~Context() {};
diff --git a/src/OpenGL/libEGL/exports.map b/src/OpenGL/libEGL/exports.map
index 24e4fb7..e41ac1e 100644
--- a/src/OpenGL/libEGL/exports.map
+++ b/src/OpenGL/libEGL/exports.map
@@ -39,8 +39,12 @@
eglCreateImageKHR;
eglDestroyImageKHR;
eglGetPlatformDisplayEXT;
- eglCreatePlatformWindowSurfaceEXT;
- eglCreatePlatformPixmapSurfaceEXT;
+ eglCreatePlatformWindowSurfaceEXT;
+ eglCreatePlatformPixmapSurfaceEXT;
+ eglCreateSyncKHR;
+ eglDestroySyncKHR;
+ eglClientWaitSyncKHR;
+ eglGetSyncAttribKHR;
libEGL_swiftshader;
diff --git a/src/OpenGL/libEGL/libEGL.cpp b/src/OpenGL/libEGL/libEGL.cpp
index 491da27..0b79fec 100644
--- a/src/OpenGL/libEGL/libEGL.cpp
+++ b/src/OpenGL/libEGL/libEGL.cpp
@@ -177,6 +177,7 @@
return success("EGL_KHR_gl_texture_2D_image "
"EGL_KHR_gl_texture_cubemap_image "
"EGL_KHR_gl_renderbuffer_image "
+ "EGL_KHR_fence_sync "
"EGL_KHR_image_base "
"EGL_ANDROID_framebuffer_target "
"EGL_ANDROID_recordable");
@@ -428,12 +429,12 @@
switch(api)
{
- case EGL_OPENGL_API:
- case EGL_OPENVG_API:
+ case EGL_OPENGL_API:
+ case EGL_OPENVG_API:
return error(EGL_BAD_PARAMETER, EGL_FALSE); // Not supported by this implementation
- case EGL_OPENGL_ES_API:
+ case EGL_OPENGL_ES_API:
break;
- default:
+ default:
return error(EGL_BAD_PARAMETER, EGL_FALSE);
}
@@ -960,6 +961,131 @@
return CreatePixmapSurface(dpy, config, (EGLNativePixmapType)native_pixmap, attrib_list);
}
+class FenceSync
+{
+public:
+ explicit FenceSync(Context *context) : context(context)
+ {
+ status = EGL_UNSIGNALED_KHR;
+ context->addRef();
+ }
+
+ ~FenceSync()
+ {
+ context->release();
+ context = nullptr;
+ }
+
+ void wait() const { return context->finish(); }
+ void signal() { status = EGL_SIGNALED_KHR; }
+ bool isSignaled() const { return status == EGL_SIGNALED_KHR; }
+
+private:
+ EGLint status;
+ Context *context;
+};
+
+EGLSyncKHR CreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
+{
+ TRACE("(EGLDisplay dpy = %p, EGLunum type = %x, EGLint *attrib_list=%p)", dpy, type, attrib_list);
+
+ egl::Display *display = static_cast<egl::Display*>(dpy);
+
+ if(!validateDisplay(display))
+ {
+ return error(EGL_BAD_DISPLAY, EGL_NO_SYNC_KHR);
+ }
+
+ if(type != EGL_SYNC_FENCE_KHR)
+ {
+ return error(EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
+ }
+
+ if(attrib_list && attrib_list[0] != EGL_NONE)
+ {
+ return error(EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
+ }
+
+ egl::Context *context = static_cast<egl::Context*>(egl::getCurrentContext());
+
+ if(!validateContext(display, context))
+ {
+ return error(EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
+ }
+
+ return new FenceSync(context);
+}
+
+EGLBoolean DestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
+{
+ TRACE("(EGLDisplay dpy = %p, EGLSyncKHR sync = %p)", dpy, sync);
+
+ egl::Display *display = static_cast<egl::Display*>(dpy);
+ FenceSync *eglSync = static_cast<FenceSync*>(sync);
+
+ if(!validateDisplay(display))
+ {
+ return error(EGL_BAD_DISPLAY, EGL_FALSE);
+ }
+
+ delete eglSync;
+
+ return EGL_TRUE;
+}
+
+EGLint ClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
+{
+ TRACE("(EGLDisplay dpy = %p, EGLSyncKHR sync = %p, EGLint flags = %x, EGLTimeKHR value = %llx)", dpy, sync, flags, timeout);
+
+ egl::Display *display = static_cast<egl::Display*>(dpy);
+ FenceSync *eglSync = static_cast<FenceSync*>(sync);
+
+ if(!validateDisplay(display))
+ {
+ return error(EGL_BAD_DISPLAY, EGL_FALSE);
+ }
+
+ (void)flags;
+ (void)timeout;
+
+ if(!eglSync->isSignaled())
+ {
+ eglSync->wait();
+ eglSync->signal();
+ }
+
+ return EGL_CONDITION_SATISFIED_KHR;
+}
+
+EGLBoolean GetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
+{
+ TRACE("(EGLDisplay dpy = %p, EGLSyncKHR sync = %p, EGLint attribute = %x, EGLint *value = %p)", dpy, sync, attribute, value);
+
+ egl::Display *display = static_cast<egl::Display*>(dpy);
+
+ if(!validateDisplay(display))
+ {
+ return error(EGL_BAD_DISPLAY, EGL_FALSE);
+ }
+
+ FenceSync *eglSync = static_cast<FenceSync*>(sync);
+
+ switch(attribute)
+ {
+ case EGL_SYNC_TYPE_KHR:
+ *value = EGL_SYNC_FENCE_KHR;
+ return EGL_TRUE;
+ case EGL_SYNC_STATUS_KHR:
+ *value = eglSync->isSignaled() ? EGL_SIGNALED_KHR : EGL_UNSIGNALED_KHR;
+ return EGL_TRUE;
+ case EGL_SYNC_CONDITION_KHR:
+ *value = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR;
+ return EGL_TRUE;
+ default:
+ return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+ }
+}
+
__eglMustCastToProperFunctionPointerType GetProcAddress(const char *procname)
{
TRACE("(const char *procname = \"%s\")", procname);
@@ -979,6 +1105,10 @@
EXTENSION(eglGetPlatformDisplayEXT),
EXTENSION(eglCreatePlatformWindowSurfaceEXT),
EXTENSION(eglCreatePlatformPixmapSurfaceEXT),
+ EXTENSION(eglCreateSyncKHR),
+ EXTENSION(eglDestroySyncKHR),
+ EXTENSION(eglClientWaitSyncKHR),
+ EXTENSION(eglGetSyncAttribKHR),
#undef EXTENSION
};
diff --git a/src/OpenGL/libEGL/libEGL.def b/src/OpenGL/libEGL/libEGL.def
index 325d241..972d87c 100644
--- a/src/OpenGL/libEGL/libEGL.def
+++ b/src/OpenGL/libEGL/libEGL.def
@@ -41,5 +41,9 @@
eglGetPlatformDisplayEXT
eglCreatePlatformWindowSurfaceEXT
eglCreatePlatformPixmapSurfaceEXT
+ eglCreateSyncKHR
+ eglDestroySyncKHR
+ eglClientWaitSyncKHR
+ eglGetSyncAttribKHR
- libEGL_swiftshader
\ No newline at end of file
+ libEGL_swiftshader
diff --git a/src/OpenGL/libEGL/libEGL.hpp b/src/OpenGL/libEGL/libEGL.hpp
index 33055ac..a2496a2 100644
--- a/src/OpenGL/libEGL/libEGL.hpp
+++ b/src/OpenGL/libEGL/libEGL.hpp
@@ -47,6 +47,10 @@
EGLImageKHR (*eglCreateImageKHR)(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
EGLBoolean (*eglDestroyImageKHR)(EGLDisplay dpy, EGLImageKHR image);
__eglMustCastToProperFunctionPointerType (*eglGetProcAddress)(const char*);
+ EGLSyncKHR (*eglCreateSyncKHR)(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
+ EGLBoolean (*eglDestroySyncKHR)(EGLDisplay dpy, EGLSyncKHR sync);
+ EGLint (*eglClientWaitSyncKHR)(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
+ EGLBoolean (*eglGetSyncAttribKHR)(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
// Functions that don't change the error code, for use by client APIs
egl::Context *(*clientGetCurrentContext)();
diff --git a/src/OpenGL/libEGL/main.cpp b/src/OpenGL/libEGL/main.cpp
index 40b53a4..c0690e7 100644
--- a/src/OpenGL/libEGL/main.cpp
+++ b/src/OpenGL/libEGL/main.cpp
@@ -359,6 +359,10 @@
EGLDisplay GetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list);
EGLSurface CreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list);
EGLSurface CreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list);
+EGLSyncKHR CreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
+EGLBoolean DestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync);
+EGLint ClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
+EGLBoolean GetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
__eglMustCastToProperFunctionPointerType GetProcAddress(const char *procname);
}
@@ -554,6 +558,26 @@
return egl::CreatePlatformPixmapSurfaceEXT(dpy, config, native_pixmap, attrib_list);
}
+EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
+{
+ return egl::CreateSyncKHR(dpy, type, attrib_list);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
+{
+ return egl::DestroySyncKHR(dpy, sync);
+}
+
+EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
+{
+ return egl::ClientWaitSyncKHR(dpy, sync, flags, timeout);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
+{
+ return egl::GetSyncAttribKHR(dpy, sync, attribute, value);
+}
+
EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress(const char *procname)
{
return egl::GetProcAddress(procname);
@@ -598,6 +622,10 @@
this->eglCreateImageKHR = egl::CreateImageKHR;
this->eglDestroyImageKHR = egl::DestroyImageKHR;
this->eglGetProcAddress = egl::GetProcAddress;
+ this->eglCreateSyncKHR = egl::CreateSyncKHR;
+ this->eglDestroySyncKHR = egl::DestroySyncKHR;
+ this->eglClientWaitSyncKHR = egl::ClientWaitSyncKHR;
+ this->eglGetSyncAttribKHR = egl::GetSyncAttribKHR;
this->clientGetCurrentContext = egl::getCurrentContext;
this->clientGetCurrentDisplay = egl::getCurrentDisplay;
diff --git a/src/OpenGL/libGLES_CM/Context.h b/src/OpenGL/libGLES_CM/Context.h
index 9c03e26..fc15144 100644
--- a/src/OpenGL/libGLES_CM/Context.h
+++ b/src/OpenGL/libGLES_CM/Context.h
@@ -294,6 +294,7 @@
virtual void makeCurrent(egl::Surface *surface);
virtual int getClientVersion() const;
+ virtual void finish();
void markAllStateDirty();
@@ -486,7 +487,6 @@
void drawArrays(GLenum mode, GLint first, GLsizei count);
void drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices);
void drawTexture(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height);
- void finish();
void flush();
void recordInvalidEnum();
diff --git a/src/OpenGL/libGLES_CM/exports.map b/src/OpenGL/libGLES_CM/exports.map
index 22246b1..dcf548f 100644
--- a/src/OpenGL/libGLES_CM/exports.map
+++ b/src/OpenGL/libGLES_CM/exports.map
@@ -205,6 +205,10 @@
glDrawTexxvOES;
glDrawTexfOES;
glDrawTexfvOES;
+ eglCreateSyncKHR;
+ eglDestroySyncKHR;
+ eglClientWaitSyncKHR;
+ eglGetSyncAttribKHR;
libGLES_CM_swiftshader;
diff --git a/src/OpenGL/libGLES_CM/libGLES_CM.cpp b/src/OpenGL/libGLES_CM/libGLES_CM.cpp
index 1951dd9..ea1291d 100644
--- a/src/OpenGL/libGLES_CM/libGLES_CM.cpp
+++ b/src/OpenGL/libGLES_CM/libGLES_CM.cpp
@@ -2273,6 +2273,7 @@
"GL_OES_depth_texture "
"GL_OES_EGL_image "
"GL_OES_EGL_image_external "
+ "GL_OES_EGL_sync "
"GL_OES_element_index_uint "
"GL_OES_framebuffer_object "
"GL_OES_packed_depth_stencil "
diff --git a/src/OpenGL/libGLES_CM/libGLES_CM.def b/src/OpenGL/libGLES_CM/libGLES_CM.def
index 0864513..cf15c8b 100644
--- a/src/OpenGL/libGLES_CM/libGLES_CM.def
+++ b/src/OpenGL/libGLES_CM/libGLES_CM.def
@@ -204,7 +204,11 @@
glDrawTexxvOES
glDrawTexfOES
glDrawTexfvOES
+ eglCreateSyncKHR
+ eglDestroySyncKHR
+ eglClientWaitSyncKHR
+ eglGetSyncAttribKHR
libGLES_CM_swiftshader
- Register
\ No newline at end of file
+ Register
diff --git a/src/OpenGL/libGLES_CM/main.cpp b/src/OpenGL/libGLES_CM/main.cpp
index 9ec5656..38a50aa 100644
--- a/src/OpenGL/libGLES_CM/main.cpp
+++ b/src/OpenGL/libGLES_CM/main.cpp
@@ -521,6 +521,26 @@
return libEGL->eglGetProcAddress(procname);
}
+EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
+{
+ return libEGL->eglCreateSyncKHR(dpy, type, attrib_list);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
+{
+ return libEGL->eglDestroySyncKHR(dpy, sync);
+}
+
+EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
+{
+ return libEGL->eglClientWaitSyncKHR(dpy, sync, flags, timeout);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
+{
+ return libEGL->eglGetSyncAttribKHR(dpy, sync, attribute, value);
+}
+
GL_API void GL_APIENTRY glActiveTexture(GLenum texture)
{
return es1::ActiveTexture(texture);
@@ -1593,4 +1613,4 @@
return &libGLES_CM;
}
-LibEGL libEGL;
\ No newline at end of file
+LibEGL libEGL;
diff --git a/src/OpenGL/libGLESv2/Context.cpp b/src/OpenGL/libGLESv2/Context.cpp
index db33e8d..9f79396 100644
--- a/src/OpenGL/libGLESv2/Context.cpp
+++ b/src/OpenGL/libGLESv2/Context.cpp
@@ -4485,6 +4485,7 @@
(const GLubyte*)"GL_OES_depth_texture_cube_map",
(const GLubyte*)"GL_OES_EGL_image",
(const GLubyte*)"GL_OES_EGL_image_external",
+ (const GLubyte*)"GL_OES_EGL_sync",
(const GLubyte*)"GL_OES_element_index_uint",
(const GLubyte*)"GL_OES_packed_depth_stencil",
(const GLubyte*)"GL_OES_rgb8_rgba8",