summaryrefslogtreecommitdiffstats
path: root/gfx/angle/checkout/src/libANGLE/renderer/EGLReusableSync.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/checkout/src/libANGLE/renderer/EGLReusableSync.cpp')
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/EGLReusableSync.cpp116
1 files changed, 116 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/EGLReusableSync.cpp b/gfx/angle/checkout/src/libANGLE/renderer/EGLReusableSync.cpp
new file mode 100644
index 0000000000..8441b028da
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/EGLReusableSync.cpp
@@ -0,0 +1,116 @@
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// EGLReusableSync.cpp: Implements the egl::ReusableSync class.
+
+#include "libANGLE/renderer/EGLReusableSync.h"
+
+#include "libANGLE/Context.h"
+#include "libANGLE/renderer/ContextImpl.h"
+
+namespace rx
+{
+
+ReusableSync::ReusableSync(const egl::AttributeMap &attribs)
+ : EGLSyncImpl(), mStatus(EGL_UNSIGNALED)
+{}
+
+void ReusableSync::onDestroy(const egl::Display *display) {}
+
+ReusableSync::~ReusableSync()
+{
+ // Release any waiting thread.
+ mCondVar.notify_all();
+}
+
+egl::Error ReusableSync::initialize(const egl::Display *display,
+ const gl::Context *context,
+ EGLenum type)
+{
+ return egl::NoError();
+}
+
+egl::Error ReusableSync::clientWait(const egl::Display *display,
+ const gl::Context *context,
+ EGLint flags,
+ EGLTime timeout,
+ EGLint *outResult)
+{
+ if (mStatus == EGL_SIGNALED)
+ {
+ *outResult = EGL_CONDITION_SATISFIED_KHR;
+ return egl::NoError();
+ }
+ if (((flags & EGL_SYNC_FLUSH_COMMANDS_BIT) != 0) && (context != nullptr))
+ {
+ angle::Result result = context->getImplementation()->flush(context);
+ if (result != angle::Result::Continue)
+ {
+ return ResultToEGL(result);
+ }
+ }
+ if (timeout == 0)
+ {
+ *outResult = EGL_TIMEOUT_EXPIRED_KHR;
+ return egl::NoError();
+ }
+
+ using NanoSeconds = std::chrono::duration<int64_t, std::nano>;
+ NanoSeconds duration = (timeout == EGL_FOREVER) ? NanoSeconds::max() : NanoSeconds(timeout);
+ std::cv_status waitStatus = std::cv_status::no_timeout;
+ mMutex.lock();
+ waitStatus = mCondVar.wait_for(mMutex, duration);
+ mMutex.unlock();
+
+ switch (waitStatus)
+ {
+ case std::cv_status::no_timeout: // Signaled.
+ *outResult = EGL_CONDITION_SATISFIED_KHR;
+ break;
+ case std::cv_status::timeout: // Timed-out.
+ *outResult = EGL_TIMEOUT_EXPIRED_KHR;
+ break;
+ default:
+ break;
+ }
+ return egl::NoError();
+}
+
+egl::Error ReusableSync::serverWait(const egl::Display *display,
+ const gl::Context *context,
+ EGLint flags)
+{
+ // Does not support server wait.
+ return egl::EglBadMatch();
+}
+
+egl::Error ReusableSync::signal(const egl::Display *display,
+ const gl::Context *context,
+ EGLint mode)
+{
+ if (mode == EGL_SIGNALED)
+ {
+ if (mStatus == EGL_UNSIGNALED)
+ {
+ // Release all threads.
+ mCondVar.notify_all();
+ }
+ mStatus = EGL_SIGNALED;
+ }
+ else
+ {
+ mStatus = EGL_UNSIGNALED;
+ }
+ return egl::NoError();
+}
+
+egl::Error ReusableSync::getStatus(const egl::Display *display, EGLint *outStatus)
+{
+ *outStatus = mStatus;
+ return egl::NoError();
+}
+
+} // namespace rx