Hash :
1ff6a6f2
Author :
Date :
2023-11-27T13:08:29
Pass the attribute map to egl::Sync::initialize. The attribute map was typically passed to the impl objects in the constructors. Instead, pass it to the initialize function. This removes the need for many member variables in different backends and opens up the future optimization of re-using sync objects by calling initialize on them with new attributes. Bug: angleproject:8430 Change-Id: If69970462cfed39d9a205034adb5ddd937c5ea31 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5063335 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
//
// 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() : EGLSyncImpl(), mStatus(0) {}
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,
const egl::AttributeMap &attribs)
{
ASSERT(type == EGL_SYNC_REUSABLE_KHR);
mStatus = EGL_UNSIGNALED;
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