summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/AsyncRequests.cpp
diff options
context:
space:
mode:
authordegasus <wickmarkus@web.de>2015-01-31 11:38:23 +0100
committerdegasus <wickmarkus@web.de>2015-02-22 08:41:15 +0100
commitbc248f8941ae5f24e651d5bf029740bc96c3df89 (patch)
treec2b209edda05a9f11f32dbfbb8549e0bffcd9616 /Source/Core/VideoCommon/AsyncRequests.cpp
parent860c889454635c0f4f7cf601f8ec77c7b81c19cd (diff)
VideoCommon: use a new async event system for efb access
Diffstat (limited to 'Source/Core/VideoCommon/AsyncRequests.cpp')
-rw-r--r--Source/Core/VideoCommon/AsyncRequests.cpp88
1 files changed, 88 insertions, 0 deletions
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<std::mutex> 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<std::mutex> 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<std::mutex> 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;
+
+ }
+}
+