mirror of
https://github.com/RPCSX/rpcsx.git
synced 2025-12-06 07:12:14 +01:00
ps4: kevent: fix Flip event
This commit is contained in:
parent
091a9eec26
commit
9bed1001bc
|
|
@ -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<uintptr_t>::max());
|
||||
void emit(sshort filter, void *userData,
|
||||
std::optional<intptr_t> (*filterFn)(void *userData, KNote *note));
|
||||
|
||||
template <typename T>
|
||||
void emit(sshort filter, T &&fn)
|
||||
requires requires(KNote *note) {
|
||||
{ fn(note) } -> std::same_as<std::optional<intptr_t>>;
|
||||
}
|
||||
{
|
||||
emit(filter, &fn, [](void *userData, KNote *note) {
|
||||
return (*static_cast<std::remove_cvref_t<T> *>(userData))(note);
|
||||
});
|
||||
}
|
||||
|
||||
void subscribe(KNote *note);
|
||||
void unsubscribe(KNote *note);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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<intptr_t> (*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);
|
||||
|
|
|
|||
|
|
@ -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<orbis::intptr_t> {
|
||||
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<std::chrono::nanoseconds>(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<orbis::intptr_t> {
|
||||
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<orbis::intptr_t> {
|
||||
if (DisplayEvent(note->event.ident >> 48) == DisplayEvent::Flip) {
|
||||
return arg;
|
||||
}
|
||||
return {};
|
||||
});
|
||||
|
||||
if (!flipComplete) {
|
||||
isImageAcquired = true;
|
||||
return;
|
||||
|
|
|
|||
Loading…
Reference in a new issue