finished sceKernelWaitEqueue implementation
This commit is contained in:
parent
98090ae42f
commit
f1b1eacb67
|
@ -9,8 +9,8 @@
|
||||||
|
|
||||||
#include <magic_enum.hpp>
|
#include <magic_enum.hpp>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "Objects/video_out_ctx.h"
|
|
||||||
|
|
||||||
|
#include "Objects/video_out_ctx.h"
|
||||||
#include "Util/Singleton.h"
|
#include "Util/Singleton.h"
|
||||||
|
|
||||||
namespace HLE::Libs::Graphics::VideoOut {
|
namespace HLE::Libs::Graphics::VideoOut {
|
||||||
|
@ -59,6 +59,11 @@ void PS4_SYSV_ABI sceVideoOutSetBufferAttribute(SceVideoOutBufferAttribute* attr
|
||||||
attribute->option = SCE_VIDEO_OUT_BUFFER_ATTRIBUTE_OPTION_NONE;
|
attribute->option = SCE_VIDEO_OUT_BUFFER_ATTRIBUTE_OPTION_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void flip_reset_event_func(HLE::Kernel::Objects::EqueueEvent* event) {
|
||||||
|
event->isTriggered = false;
|
||||||
|
event->event.fflags = 0;
|
||||||
|
event->event.data = 0;
|
||||||
|
}
|
||||||
s32 PS4_SYSV_ABI sceVideoOutAddFlipEvent(LibKernel::EventQueues::SceKernelEqueue eq, s32 handle, void* udata) {
|
s32 PS4_SYSV_ABI sceVideoOutAddFlipEvent(LibKernel::EventQueues::SceKernelEqueue eq, s32 handle, void* udata) {
|
||||||
PRINT_FUNCTION_NAME();
|
PRINT_FUNCTION_NAME();
|
||||||
auto* videoOut = Singleton<HLE::Graphics::Objects::VideoOutCtx>::Instance();
|
auto* videoOut = Singleton<HLE::Graphics::Objects::VideoOutCtx>::Instance();
|
||||||
|
@ -82,7 +87,7 @@ s32 PS4_SYSV_ABI sceVideoOutAddFlipEvent(LibKernel::EventQueues::SceKernelEqueue
|
||||||
event.event.fflags = 0;
|
event.event.fflags = 0;
|
||||||
event.event.data = 0;
|
event.event.data = 0;
|
||||||
// event.filter.delete_event_func = flip_event_delete_func;//called in sceKernelDeleteEvent //TODO
|
// event.filter.delete_event_func = flip_event_delete_func;//called in sceKernelDeleteEvent //TODO
|
||||||
// event.filter.reset_event_func = flip_event_reset_func;//called in sceKernelWaitEqueue //TODO
|
event.filter.reset_event_func = flip_reset_event_func;
|
||||||
// event.filter.trigger_event_func = flip_event_trigger_func;//called in sceKernelTriggerEvent //TODO
|
// event.filter.trigger_event_func = flip_event_trigger_func;//called in sceKernelTriggerEvent //TODO
|
||||||
event.filter.data = ctx;
|
event.filter.data = ctx;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#include "event_queue.h"
|
#include "event_queue.h"
|
||||||
|
|
||||||
|
#include <Lib/Timer.h>
|
||||||
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
namespace HLE::Kernel::Objects {
|
namespace HLE::Kernel::Objects {
|
||||||
|
@ -21,4 +23,51 @@ int EqueueInternal::addEvent(const EqueueEvent& event) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int EqueueInternal::waitForEvents(SceKernelEvent* ev, int num, u32 micros) {
|
||||||
|
Lib::LockMutexGuard lock(m_mutex);
|
||||||
|
|
||||||
|
u32 timeElapsed = 0;
|
||||||
|
Lib::Timer t;
|
||||||
|
t.Start();
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
int ret = getTriggeredEvents(ev, num);
|
||||||
|
|
||||||
|
if (ret > 0 || (timeElapsed >= micros && micros != 0)) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (micros == 0) {
|
||||||
|
m_cond.WaitCondVar(&m_mutex);
|
||||||
|
} else {
|
||||||
|
m_cond.WaitCondVarFor(&m_mutex, micros - timeElapsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
timeElapsed = static_cast<uint32_t>(t.GetTimeSec() * 1000000.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int EqueueInternal::getTriggeredEvents(SceKernelEvent* ev, int num) {
|
||||||
|
Lib::LockMutexGuard lock(m_mutex);
|
||||||
|
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (m_events.size() > 1) {
|
||||||
|
BREAKPOINT(); // we currently support one event
|
||||||
|
}
|
||||||
|
auto& event = m_events[0];
|
||||||
|
|
||||||
|
if (event.isTriggered) {
|
||||||
|
ev[ret++] = event.event;
|
||||||
|
|
||||||
|
if (event.filter.reset_event_func != nullptr) {
|
||||||
|
event.filter.reset_event_func(&event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
}; // namespace HLE::Kernel::Objects
|
}; // namespace HLE::Kernel::Objects
|
|
@ -50,7 +50,7 @@ struct SceKernelEvent {
|
||||||
struct Filter {
|
struct Filter {
|
||||||
void* data = nullptr;
|
void* data = nullptr;
|
||||||
TriggerFunc trigger_event_func = nullptr;
|
TriggerFunc trigger_event_func = nullptr;
|
||||||
ResetFunc reset__event_func = nullptr;
|
ResetFunc reset_event_func = nullptr;
|
||||||
DeleteFunc delete_event_func = nullptr;
|
DeleteFunc delete_event_func = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -66,9 +66,12 @@ class EqueueInternal {
|
||||||
virtual ~EqueueInternal();
|
virtual ~EqueueInternal();
|
||||||
void setName(const std::string& m_name) { this->m_name = m_name; }
|
void setName(const std::string& m_name) { this->m_name = m_name; }
|
||||||
int addEvent(const EqueueEvent& event);
|
int addEvent(const EqueueEvent& event);
|
||||||
|
int waitForEvents(SceKernelEvent* ev, int num, u32 micros);
|
||||||
|
int getTriggeredEvents(SceKernelEvent* ev, int num);
|
||||||
private:
|
private:
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
Lib::Mutex m_mutex;
|
Lib::Mutex m_mutex;
|
||||||
std::vector<EqueueEvent> m_events;
|
std::vector<EqueueEvent> m_events;
|
||||||
|
Lib::ConditionVariable m_cond;
|
||||||
};
|
};
|
||||||
}; // namespace HLE::Kernel::Objects
|
}; // namespace HLE::Kernel::Objects
|
|
@ -51,7 +51,7 @@ int PS4_SYSV_ABI sceKernelWaitEqueue(SceKernelEqueue eq, HLE::Kernel::Objects::S
|
||||||
return SCE_KERNEL_ERROR_EINVAL;
|
return SCE_KERNEL_ERROR_EINVAL;
|
||||||
}
|
}
|
||||||
if (timo == nullptr) { // wait until an event arrives without timing out
|
if (timo == nullptr) { // wait until an event arrives without timing out
|
||||||
// BREAKPOINT();//NOT supported yet TODO
|
*out = eq->waitForEvents(ev, num, 0);
|
||||||
}
|
}
|
||||||
if (timo != nullptr) {
|
if (timo != nullptr) {
|
||||||
if (*timo == 0) {//only events that have already arrived at the time of this function call can be received
|
if (*timo == 0) {//only events that have already arrived at the time of this function call can be received
|
||||||
|
|
Loading…
Reference in New Issue