From 9bed1001bc05c42dbb9d0f0eaeea029aa22113b1 Mon Sep 17 00:00:00 2001 From: DH Date: Sun, 24 Nov 2024 20:50:28 +0300 Subject: [PATCH] ps4: kevent: fix Flip event --- orbis-kernel/include/orbis/note.hpp | 14 ++++++++++++++ orbis-kernel/src/event.cpp | 24 +++++++++++++++++++++++ rpcsx/gpu/Device.cpp | 30 ++++++++++++++++++++++++----- 3 files changed, 63 insertions(+), 5 deletions(-) diff --git a/orbis-kernel/include/orbis/note.hpp b/orbis-kernel/include/orbis/note.hpp index ce96e5c14..5a8a37a8a 100644 --- a/orbis-kernel/include/orbis/note.hpp +++ b/orbis-kernel/include/orbis/note.hpp @@ -93,6 +93,20 @@ struct EventEmitter : orbis::RcBase { void emit(sshort filter, uint fflags = 0, intptr_t data = 0, uintptr_t ident = std::numeric_limits::max()); + void emit(sshort filter, void *userData, + std::optional (*filterFn)(void *userData, KNote *note)); + + template + void emit(sshort filter, T &&fn) + requires requires(KNote *note) { + { fn(note) } -> std::same_as>; + } + { + emit(filter, &fn, [](void *userData, KNote *note) { + return (*static_cast *>(userData))(note); + }); + } + void subscribe(KNote *note); void unsubscribe(KNote *note); }; diff --git a/orbis-kernel/src/event.cpp b/orbis-kernel/src/event.cpp index 82f275760..c9e9ef194 100644 --- a/orbis-kernel/src/event.cpp +++ b/orbis-kernel/src/event.cpp @@ -53,6 +53,30 @@ void orbis::EventEmitter::emit(sshort filter, uint fflags, intptr_t data, } } +void orbis::EventEmitter::emit( + sshort filter, void *userData, + std::optional (*filterFn)(void *userData, KNote *note)) { + std::lock_guard lock(mutex); + + for (auto note : notes) { + if (note->event.filter != filter) { + continue; + } + + std::lock_guard lock(note->mutex); + + if (note->triggered) { + continue; + } + + if (auto data = filterFn(userData, note)) { + note->event.data = *data; + note->triggered = true; + note->queue->cv.notify_all(note->queue->mtx); + } + } +} + void orbis::EventEmitter::subscribe(KNote *note) { std::lock_guard lock(mutex); notes.insert(note); diff --git a/rpcsx/gpu/Device.cpp b/rpcsx/gpu/Device.cpp index 8997c3859..ecf2e99ea 100644 --- a/rpcsx/gpu/Device.cpp +++ b/rpcsx/gpu/Device.cpp @@ -335,8 +335,15 @@ void Device::start() { std::jthread vblankThread([](const std::stop_token &stopToken) { orbis::g_context.deviceEventEmitter->emit( - orbis::kEvFiltDisplay, 0, - makeDisplayEvent(DisplayEvent::PreVBlankStart)); + orbis::kEvFiltDisplay, + [=](orbis::KNote *note) -> std::optional { + if (DisplayEvent(note->event.ident >> 48) == + DisplayEvent::PreVBlankStart) { + return 0; + } + return {}; + }); + auto prevVBlank = std::chrono::steady_clock::now(); auto period = std::chrono::seconds(1) / 59.94; @@ -344,8 +351,15 @@ void Device::start() { prevVBlank += std::chrono::duration_cast(period); std::this_thread::sleep_until(prevVBlank); + orbis::g_context.deviceEventEmitter->emit( - orbis::kEvFiltDisplay, 0, 0, makeDisplayEvent(DisplayEvent::VBlank)); + orbis::kEvFiltDisplay, + [=](orbis::KNote *note) -> std::optional { + if (DisplayEvent(note->event.ident >> 48) == DisplayEvent::VBlank) { + return 0; + } + return {}; + }); } }); @@ -908,8 +922,14 @@ void Device::flip(std::uint32_t pid, int bufferIndex, std::uint64_t arg) { vk::context->swapchainImageViews[imageIndex]); orbis::g_context.deviceEventEmitter->emit( - orbis::kEvFiltDisplay, 0, arg, - makeDisplayEvent(DisplayEvent::Flip, 1 << 8, 0)); + orbis::kEvFiltDisplay, + [=](orbis::KNote *note) -> std::optional { + if (DisplayEvent(note->event.ident >> 48) == DisplayEvent::Flip) { + return arg; + } + return {}; + }); + if (!flipComplete) { isImageAcquired = true; return;