From bc248f8941ae5f24e651d5bf029740bc96c3df89 Mon Sep 17 00:00:00 2001 From: degasus Date: Sat, 31 Jan 2015 11:38:23 +0100 Subject: VideoCommon: use a new async event system for efb access --- Source/Core/VideoCommon/AsyncRequests.cpp | 88 +++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 Source/Core/VideoCommon/AsyncRequests.cpp (limited to 'Source/Core/VideoCommon/AsyncRequests.cpp') diff --git a/Source/Core/VideoCommon/AsyncRequests.cpp b/Source/Core/VideoCommon/AsyncRequests.cpp new file mode 100644 index 0000000000..dce56c0d7b --- /dev/null +++ b/Source/Core/VideoCommon/AsyncRequests.cpp @@ -0,0 +1,88 @@ +#include "VideoCommon/AsyncRequests.h" +#include "VideoCommon/RenderBase.h" + +AsyncRequests AsyncRequests::s_singleton; + +AsyncRequests::AsyncRequests() +: m_enable(false) +{ +} + +void AsyncRequests::PullEventsInternal() +{ + std::unique_lock lock(m_mutex); + m_empty.store(true); + + while (!m_queue.empty()) + { + const Event& e = m_queue.front(); + + lock.unlock(); + HandleEvent(e); + lock.lock(); + + m_queue.pop(); + } + + if (m_wake_me_up_again) + { + m_wake_me_up_again = false; + m_cond.notify_all(); + } +} + +void AsyncRequests::PushEvent(const AsyncRequests::Event& event, bool blocking) +{ + std::unique_lock lock(m_mutex); + m_empty.store(false); + m_wake_me_up_again |= blocking; + + if (!m_enable) + return; + + m_queue.push(event); + + if (blocking) + { + m_cond.wait(lock, [this]{return m_queue.empty();}); + } +} + +void AsyncRequests::SetEnable(bool enable) +{ + std::unique_lock lock(m_mutex); + m_enable = enable; + + if (!enable) + { + // flush the queue on disabling + while (!m_queue.empty()) + m_queue.pop(); + if (m_wake_me_up_again) + m_cond.notify_all(); + } +} + +void AsyncRequests::HandleEvent(const AsyncRequests::Event& e) +{ + switch (e.type) + { + case Event::EFB_POKE_COLOR: + g_renderer->AccessEFB(POKE_COLOR, e.efb_poke.x, e.efb_poke.y, e.efb_poke.data); + break; + + case Event::EFB_POKE_Z: + g_renderer->AccessEFB(POKE_Z, e.efb_poke.x, e.efb_poke.y, e.efb_poke.data); + break; + + case Event::EFB_PEEK_COLOR: + *e.efb_peek.data = g_renderer->AccessEFB(PEEK_COLOR, e.efb_peek.x, e.efb_peek.y, 0); + break; + + case Event::EFB_PEEK_Z: + *e.efb_peek.data = g_renderer->AccessEFB(PEEK_Z, e.efb_peek.x, e.efb_peek.y, 0); + break; + + } +} + -- cgit v1.2.3