Skip to content

Commit

Permalink
ps4: kevent: fix Flip event
Browse files Browse the repository at this point in the history
  • Loading branch information
DHrpcs3 committed Nov 24, 2024
1 parent 091a9ee commit 9bed100
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 5 deletions.
14 changes: 14 additions & 0 deletions orbis-kernel/include/orbis/note.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
};
Expand Down
24 changes: 24 additions & 0 deletions orbis-kernel/src/event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
30 changes: 25 additions & 5 deletions rpcsx/gpu/Device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -335,17 +335,31 @@ 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;

while (!stopToken.stop_requested()) {
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 {};
});
}
});

Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 9bed100

Please sign in to comment.