diff options
-rw-r--r-- | src/tdm_backend_drm.c | 5 | ||||
-rw-r--r-- | src/tdm_backend_drm_types.h | 2 | ||||
-rw-r--r-- | src/tdm_drm_display.c | 9 |
3 files changed, 15 insertions, 1 deletions
diff --git a/src/tdm_backend_drm.c b/src/tdm_backend_drm.c index dfd3645..4d3cd85 100644 --- a/src/tdm_backend_drm.c +++ b/src/tdm_backend_drm.c @@ -299,6 +299,11 @@ _tdm_drm_display_initialize(tdm_drm_display *display_data) char errno_buf[256] = {0,}; char *errno_msg; hal_tdm_error ret; + drmVersion *version = drmGetVersion(display_data->drm_fd); + + if (strcmp(version->name, "virtio_gpu") == 0) + display_data->periodic_vblank_broken = true; + drmFreeVersion(version); #if LIBDRM_MAJOR_VERSION >= 2 && LIBDRM_MINOR_VERSION >= 4 && LIBDRM_MICRO_VERSION >= 47 if (drmSetClientCap(display_data->drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1) < 0) { diff --git a/src/tdm_backend_drm_types.h b/src/tdm_backend_drm_types.h index 356d8ec..fc553d0 100644 --- a/src/tdm_backend_drm_types.h +++ b/src/tdm_backend_drm_types.h @@ -159,6 +159,8 @@ struct _tdm_drm_display { struct list_head output_list; struct list_head buffer_list; + + int periodic_vblank_broken; }; struct _tdm_drm_display_buffer { diff --git a/src/tdm_drm_display.c b/src/tdm_drm_display.c index ea403b0..60f1df6 100644 --- a/src/tdm_drm_display.c +++ b/src/tdm_drm_display.c @@ -182,7 +182,14 @@ _tdm_drm_display_commit_primary_layer(tdm_drm_layer *layer_data, return HAL_TDM_ERROR_OPERATION_FAILED; } - _tdm_drm_output_update_status(output_data, HAL_TDM_OUTPUT_CONN_STATUS_MODE_SETTED); + /* + * Don't report setted mode if underlaying DRM driver doesn't handle + * periodic vblank events properly. This way libtdm will keep serving + * software timer based events instead of switching to (broken) vblank + * events. + */ + if (!display_data->periodic_vblank_broken) + _tdm_drm_output_update_status(output_data, HAL_TDM_OUTPUT_CONN_STATUS_MODE_SETTED); *do_waitvblank = 1; return HAL_TDM_ERROR_NONE; |