#include "XCEngine/RHI/OpenGL/OpenGLFence.h" #include namespace XCEngine { namespace RHI { OpenGLFence::OpenGLFence() : m_sync(nullptr) , m_fenceValue(0) , m_completedValue(0) , m_signaled(false) { } OpenGLFence::~OpenGLFence() { Shutdown(); } bool OpenGLFence::Initialize(bool signaled) { m_fenceValue = signaled ? 1 : 0; m_completedValue = m_fenceValue; m_signaled = signaled; return true; } void OpenGLFence::Shutdown() { if (m_sync) { glDeleteSync(static_cast(m_sync)); m_sync = nullptr; } } void OpenGLFence::Signal() { glFlush(); m_fenceValue++; m_signaled = true; } void OpenGLFence::Signal(uint64_t value) { glFlush(); m_fenceValue = value; m_signaled = true; } void OpenGLFence::Wait(uint64_t timeoutNs) { if (!m_signaled || !m_sync) { glFinish(); m_completedValue = m_fenceValue; m_signaled = true; return; } GLsync sync = static_cast(m_sync); GLenum result = glClientWaitSync(sync, GL_SYNC_FLUSH_COMMANDS_BIT, timeoutNs); while (result == GL_TIMEOUT_EXPIRED && timeoutNs > 0) { result = glClientWaitSync(sync, 0, timeoutNs); } if (result == GL_ALREADY_SIGNALED || result == GL_CONDITION_SATISFIED) { m_completedValue = m_fenceValue; } } void OpenGLFence::Reset() { if (m_sync) { glDeleteSync(static_cast(m_sync)); m_sync = nullptr; } m_signaled = false; } bool OpenGLFence::IsSignaled() const { return m_signaled; } FenceStatus OpenGLFence::GetStatus() const { if (!m_sync) { return m_signaled ? FenceStatus::Signaled : FenceStatus::Unsignaled; } GLsync sync = static_cast(m_sync); GLint status = 0; glGetSynciv(sync, GL_SYNC_STATUS, sizeof(status), nullptr, &status); if (status == GL_SIGNALED) { return FenceStatus::Signaled; } return FenceStatus::Unsignaled; } uint64_t OpenGLFence::GetCompletedValue() const { return m_completedValue; } } // namespace RHI } // namespace XCEngine