[mutter] gpu-kms: poll() on KMS fd on EAGAIN
- From: Jonas Ådahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] gpu-kms: poll() on KMS fd on EAGAIN
- Date: Fri, 6 Oct 2017 18:24:51 +0000 (UTC)
commit 406359bba154e60aab2a14666eb5e183c1c0e1cf
Author: Jonas Ådahl <jadahl gmail com>
Date: Mon Jul 24 10:50:49 2017 +0800
gpu-kms: poll() on KMS fd on EAGAIN
When drmHandleEvent() returns an error and errno is set to EAGAIN,
instead of ending up in a busy loop, poll() the fd until there is
anything to read.
https://bugzilla.gnome.org/show_bug.cgi?id=785381
src/backends/native/meta-gpu-kms.c | 45 ++++++++++++++++++++++++---
src/backends/native/meta-gpu-kms.h | 3 +-
src/backends/native/meta-renderer-native.c | 4 +-
3 files changed, 44 insertions(+), 8 deletions(-)
---
diff --git a/src/backends/native/meta-gpu-kms.c b/src/backends/native/meta-gpu-kms.c
index 775ed34..0b70c38 100644
--- a/src/backends/native/meta-gpu-kms.c
+++ b/src/backends/native/meta-gpu-kms.c
@@ -25,6 +25,7 @@
#include <drm.h>
#include <errno.h>
+#include <poll.h>
#include <string.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
@@ -80,7 +81,7 @@ kms_event_dispatch (GSource *source,
{
MetaKmsSource *kms_source = (MetaKmsSource *) source;
- meta_gpu_kms_wait_for_flip (kms_source->gpu_kms);
+ meta_gpu_kms_wait_for_flip (kms_source->gpu_kms, NULL);
return G_SOURCE_CONTINUE;
}
@@ -256,18 +257,52 @@ page_flip_handler (int fd,
invoke_flip_closure (flip_closure);
}
-void
-meta_gpu_kms_wait_for_flip (MetaGpuKms *gpu_kms)
+gboolean
+meta_gpu_kms_wait_for_flip (MetaGpuKms *gpu_kms,
+ GError **error)
{
drmEventContext evctx;
if (gpu_kms->page_flips_not_supported)
- return;
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Page flips not supported");
+ return FALSE;
+ }
memset (&evctx, 0, sizeof evctx);
evctx.version = DRM_EVENT_CONTEXT_VERSION;
evctx.page_flip_handler = page_flip_handler;
- drmHandleEvent (gpu_kms->fd, &evctx);
+
+ while (TRUE)
+ {
+ if (drmHandleEvent (gpu_kms->fd, &evctx) != 0)
+ {
+ struct pollfd pfd;
+ int ret;
+
+ if (errno != EAGAIN)
+ {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ strerror (errno));
+ return FALSE;
+ }
+
+ pfd.fd = gpu_kms->fd;
+ pfd.events = POLL_IN | POLL_ERR;
+ do
+ {
+ ret = poll (&pfd, 1, -1);
+ }
+ while (ret == -1 && errno == EINTR);
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ return TRUE;
}
void
diff --git a/src/backends/native/meta-gpu-kms.h b/src/backends/native/meta-gpu-kms.h
index 001fc95..6c7d5a3 100644
--- a/src/backends/native/meta-gpu-kms.h
+++ b/src/backends/native/meta-gpu-kms.h
@@ -62,7 +62,8 @@ gboolean meta_gpu_kms_flip_crtc (MetaGpuKms *gpu_kms,
GClosure *flip_closure,
gboolean *fb_in_use);
-void meta_gpu_kms_wait_for_flip (MetaGpuKms *gpu_kms);
+gboolean meta_gpu_kms_wait_for_flip (MetaGpuKms *gpu_kms,
+ GError **error);
int meta_gpu_kms_get_fd (MetaGpuKms *gpu_kms);
diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
index 4fdaeb4..8a54e9b 100644
--- a/src/backends/native/meta-renderer-native.c
+++ b/src/backends/native/meta-renderer-native.c
@@ -944,7 +944,7 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
* animation earlier due to the animation being driven by some other monitor.
*/
while (onscreen_native->pending_flips)
- meta_gpu_kms_wait_for_flip (gpu_kms);
+ meta_gpu_kms_wait_for_flip (gpu_kms, NULL);
parent_vtable->onscreen_swap_buffers_with_damage (onscreen,
rectangles,
@@ -1658,7 +1658,7 @@ meta_renderer_native_set_legacy_view_size (MetaRendererNative *renderer_native,
* to swap the current buffer.
*/
while (onscreen_native->gbm.next_fb_id != 0)
- meta_gpu_kms_wait_for_flip (gpu_kms);
+ meta_gpu_kms_wait_for_flip (gpu_kms, NULL);
/* Need to drop the GBM surface and create a new one */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]