// // 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; 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