Edit

kc3-lang/angle/src/libANGLE/renderer/EGLReusableSync.cpp

Branch :

  • Show log

    Commit

  • Author : Jeff Vigil
    Date : 2020-10-14 10:27:56
    Hash : 00a49766
    Message : EGL: Implement EGL_KHR_reusable_sync Add extension string and flags Add EGLReusableSync files to libANGLE and gni Test: angle_deqp_egl_tests --deqp-case=dEQP-EGL.functional.reusable_sync.* --deqp-case=dEQP-EGL.functional.fence_sync.* Bug: angleproject:5168 Change-Id: I967a10cf387047c9ee1963acfc854a8288325a8e Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2477293 Commit-Queue: Jeff Vigil <j.vigil@samsung.com> Commit-Queue: Mohan Maiya <m.maiya@samsung.com> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Jamie Madill <jmadill@chromium.org>

  • src/libANGLE/renderer/EGLReusableSync.cpp
  • //
    // 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