EGLReusableSync.cpp (3204B)
1 // 2 // Copyright 2020 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 7 // EGLReusableSync.cpp: Implements the egl::ReusableSync class. 8 9 #include "libANGLE/renderer/EGLReusableSync.h" 10 11 #include "libANGLE/Context.h" 12 #include "libANGLE/renderer/ContextImpl.h" 13 14 namespace rx 15 { 16 17 ReusableSync::ReusableSync(const egl::AttributeMap &attribs) 18 : EGLSyncImpl(), mStatus(EGL_UNSIGNALED) 19 {} 20 21 void ReusableSync::onDestroy(const egl::Display *display) {} 22 23 ReusableSync::~ReusableSync() 24 { 25 // Release any waiting thread. 26 mCondVar.notify_all(); 27 } 28 29 egl::Error ReusableSync::initialize(const egl::Display *display, 30 const gl::Context *context, 31 EGLenum type) 32 { 33 return egl::NoError(); 34 } 35 36 egl::Error ReusableSync::clientWait(const egl::Display *display, 37 const gl::Context *context, 38 EGLint flags, 39 EGLTime timeout, 40 EGLint *outResult) 41 { 42 if (mStatus == EGL_SIGNALED) 43 { 44 *outResult = EGL_CONDITION_SATISFIED_KHR; 45 return egl::NoError(); 46 } 47 if (((flags & EGL_SYNC_FLUSH_COMMANDS_BIT) != 0) && (context != nullptr)) 48 { 49 angle::Result result = context->getImplementation()->flush(context); 50 if (result != angle::Result::Continue) 51 { 52 return ResultToEGL(result); 53 } 54 } 55 if (timeout == 0) 56 { 57 *outResult = EGL_TIMEOUT_EXPIRED_KHR; 58 return egl::NoError(); 59 } 60 61 using NanoSeconds = std::chrono::duration<int64_t, std::nano>; 62 NanoSeconds duration = (timeout == EGL_FOREVER) ? NanoSeconds::max() : NanoSeconds(timeout); 63 std::cv_status waitStatus = std::cv_status::no_timeout; 64 mMutex.lock(); 65 waitStatus = mCondVar.wait_for(mMutex, duration); 66 mMutex.unlock(); 67 68 switch (waitStatus) 69 { 70 case std::cv_status::no_timeout: // Signaled. 71 *outResult = EGL_CONDITION_SATISFIED_KHR; 72 break; 73 case std::cv_status::timeout: // Timed-out. 74 *outResult = EGL_TIMEOUT_EXPIRED_KHR; 75 break; 76 default: 77 break; 78 } 79 return egl::NoError(); 80 } 81 82 egl::Error ReusableSync::serverWait(const egl::Display *display, 83 const gl::Context *context, 84 EGLint flags) 85 { 86 // Does not support server wait. 87 return egl::EglBadMatch(); 88 } 89 90 egl::Error ReusableSync::signal(const egl::Display *display, 91 const gl::Context *context, 92 EGLint mode) 93 { 94 if (mode == EGL_SIGNALED) 95 { 96 if (mStatus == EGL_UNSIGNALED) 97 { 98 // Release all threads. 99 mCondVar.notify_all(); 100 } 101 mStatus = EGL_SIGNALED; 102 } 103 else 104 { 105 mStatus = EGL_UNSIGNALED; 106 } 107 return egl::NoError(); 108 } 109 110 egl::Error ReusableSync::getStatus(const egl::Display *display, EGLint *outStatus) 111 { 112 *outStatus = mStatus; 113 return egl::NoError(); 114 } 115 116 } // namespace rx