Don't busy loop during wlgrab capture
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
* @file src/platform/linux/wayland.cpp
|
* @file src/platform/linux/wayland.cpp
|
||||||
* @brief todo
|
* @brief todo
|
||||||
*/
|
*/
|
||||||
|
#include <poll.h>
|
||||||
#include <wayland-client.h>
|
#include <wayland-client.h>
|
||||||
#include <wayland-util.h>
|
#include <wayland-util.h>
|
||||||
|
|
||||||
@@ -61,6 +62,38 @@ namespace wl {
|
|||||||
wl_display_roundtrip(display_internal.get());
|
wl_display_roundtrip(display_internal.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Waits up to the specified timeout to dispatch new events on the wl_display.
|
||||||
|
* @param timeout The timeout in milliseconds.
|
||||||
|
* @return true if new events were dispatched or false if the timeout expired.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
display_t::dispatch(std::chrono::milliseconds timeout) {
|
||||||
|
// Check if any events are queued already. If not, flush
|
||||||
|
// outgoing events, and prepare to wait for readability.
|
||||||
|
if (wl_display_prepare_read(display_internal.get()) == 0) {
|
||||||
|
wl_display_flush(display_internal.get());
|
||||||
|
|
||||||
|
// Wait for an event to come in
|
||||||
|
struct pollfd pfd = {};
|
||||||
|
pfd.fd = wl_display_get_fd(display_internal.get());
|
||||||
|
pfd.events = POLLIN;
|
||||||
|
if (poll(&pfd, 1, timeout.count()) == 1 && (pfd.revents & POLLIN)) {
|
||||||
|
// Read the new event(s)
|
||||||
|
wl_display_read_events(display_internal.get());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// We timed out, so unlock the queue now
|
||||||
|
wl_display_cancel_read(display_internal.get());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dispatch any existing or new pending events
|
||||||
|
wl_display_dispatch_pending(display_internal.get());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
wl_registry *
|
wl_registry *
|
||||||
display_t::registry() {
|
display_t::registry() {
|
||||||
return wl_display_get_registry(display_internal.get());
|
return wl_display_get_registry(display_internal.get());
|
||||||
|
|||||||
@@ -206,6 +206,10 @@ namespace wl {
|
|||||||
void
|
void
|
||||||
roundtrip();
|
roundtrip();
|
||||||
|
|
||||||
|
// Wait up to the timeout to read and dispatch new events
|
||||||
|
bool
|
||||||
|
dispatch(std::chrono::milliseconds timeout);
|
||||||
|
|
||||||
// Get the registry associated with the display
|
// Get the registry associated with the display
|
||||||
// No need to manually free the registry
|
// No need to manually free the registry
|
||||||
wl_registry *
|
wl_registry *
|
||||||
|
|||||||
@@ -87,11 +87,11 @@ namespace wl {
|
|||||||
snapshot(const pull_free_image_cb_t &pull_free_image_cb, std::shared_ptr<platf::img_t> &img_out, std::chrono::milliseconds timeout, bool cursor) {
|
snapshot(const pull_free_image_cb_t &pull_free_image_cb, std::shared_ptr<platf::img_t> &img_out, std::chrono::milliseconds timeout, bool cursor) {
|
||||||
auto to = std::chrono::steady_clock::now() + timeout;
|
auto to = std::chrono::steady_clock::now() + timeout;
|
||||||
|
|
||||||
|
// Dispatch events until we get a new frame or the timeout expires
|
||||||
dmabuf.listen(interface.dmabuf_manager, output, cursor);
|
dmabuf.listen(interface.dmabuf_manager, output, cursor);
|
||||||
do {
|
do {
|
||||||
display.roundtrip();
|
auto remaining_time_ms = std::chrono::duration_cast<std::chrono::milliseconds>(to - std::chrono::steady_clock::now());
|
||||||
|
if (remaining_time_ms.count() < 0 || !display.dispatch(remaining_time_ms)) {
|
||||||
if (to < std::chrono::steady_clock::now()) {
|
|
||||||
return platf::capture_e::timeout;
|
return platf::capture_e::timeout;
|
||||||
}
|
}
|
||||||
} while (dmabuf.status == dmabuf_t::WAITING);
|
} while (dmabuf.status == dmabuf_t::WAITING);
|
||||||
|
|||||||
Reference in New Issue
Block a user