From 7f519f3d6d474e7ca2d37f3fe4abbaba87e4086d Mon Sep 17 00:00:00 2001 From: Matthew Kosarek Date: Wed, 18 Oct 2023 13:38:01 -0400 Subject: [PATCH] Combining paths for configure and queue_atomic_flip --- .../eglstream-kms/server/egl_output.cpp | 90 ++++++++----------- .../eglstream-kms/server/egl_output.h | 3 + 2 files changed, 38 insertions(+), 55 deletions(-) diff --git a/src/platforms/eglstream-kms/server/egl_output.cpp b/src/platforms/eglstream-kms/server/egl_output.cpp index f67cebead5..d6bad33d8d 100644 --- a/src/platforms/eglstream-kms/server/egl_output.cpp +++ b/src/platforms/eglstream-kms/server/egl_output.cpp @@ -212,21 +212,14 @@ int mgek::EGLOutput::max_refresh_rate() const void mgek::EGLOutput::configure(size_t kms_mode_index) { mode_index = kms_mode_index; - auto const width = connector->modes[kms_mode_index].hdisplay; - auto const height = connector->modes[kms_mode_index].vdisplay; - - std::unique_ptr - request{drmModeAtomicAlloc(), &drmModeAtomicFree}; + refresh_connector(drm_fd, connector); mgk::DRMModeCrtcUPtr crtc; mgk::DRMModePlaneUPtr plane; - - refresh_connector(drm_fd, connector); - std::tie(crtc, plane) = mgk::find_crtc_with_primary_plane(drm_fd, connector); auto const crtc_id = crtc->crtc_id; + plane_id = plane->plane_id; - uint32_t mode_id{0}; auto ret = drmModeCreatePropertyBlob( drm_fd, &connector->modes[kms_mode_index], @@ -239,47 +232,10 @@ void mgek::EGLOutput::configure(size_t kms_mode_index) std::system_error(-ret, std::system_category(), "Failed to create DRM Mode property blob")); } + auto const width = connector->modes[mode_index].hdisplay; + auto const height = connector->modes[mode_index].vdisplay; CPUAddressableFb dummy{drm_fd, width, height}; - - mgk::ObjectProperties crtc_props{drm_fd, crtc_id, DRM_MODE_OBJECT_CRTC}; - - /* Activate the CRTC and set the mode */ - drmModeAtomicAddProperty(request.get(), crtc_id, crtc_props.id_for("MODE_ID"), mode_id); - drmModeAtomicAddProperty(request.get(), crtc_id, crtc_props.id_for("ACTIVE"), 1); - - /* Set CRTC for the output */ - auto const connector_id = connector->connector_id; - mgk::ObjectProperties connector_props{drm_fd, connector_id, DRM_MODE_OBJECT_CONNECTOR}; - drmModeAtomicAddProperty(request.get(), connector_id, connector_props.id_for("CRTC_ID"), crtc_id); - - /* Set up the output plane... */ - plane_id = plane->plane_id; - plane_props = std::make_unique(drm_fd, plane_id, DRM_MODE_OBJECT_PLANE); - - /* Source viewport. Coordinates are 16.16 fixed point format */ - drmModeAtomicAddProperty(request.get(), plane_id, plane_props->id_for("SRC_X"), 0); - drmModeAtomicAddProperty(request.get(), plane_id, plane_props->id_for("SRC_Y"), 0); - drmModeAtomicAddProperty(request.get(), plane_id, plane_props->id_for("SRC_W"), width << 16); - drmModeAtomicAddProperty(request.get(), plane_id, plane_props->id_for("SRC_H"), height << 16); - - /* Destination viewport. Coordinates are *not* 16.16 */ - drmModeAtomicAddProperty(request.get(), plane_id, plane_props->id_for("CRTC_X"), 0); - drmModeAtomicAddProperty(request.get(), plane_id, plane_props->id_for("CRTC_Y"), 0); - drmModeAtomicAddProperty(request.get(), plane_id, plane_props->id_for("CRTC_W"), width); - drmModeAtomicAddProperty(request.get(), plane_id, plane_props->id_for("CRTC_H"), height); - - /* Set a surface for the plane, and connect to the CRTC */ - drmModeAtomicAddProperty(request.get(), plane_id, plane_props->id_for("FB_ID"), dummy.id()); - drmModeAtomicAddProperty(request.get(), plane_id, plane_props->id_for("CRTC_ID"), crtc_id); - - /* We don't monitor the DRM events (yet), so have no userdata */ - ret = drmModeAtomicCommit(drm_fd, request.get(), DRM_MODE_ATOMIC_ALLOW_MODESET, nullptr); - - if (ret != 0) - { - BOOST_THROW_EXCEPTION( - std::system_error(-ret, std::system_category(), "Failed to commit atomic KMS configuration change")); - } + atomic_commit(dummy.id(), nullptr, DRM_MODE_ATOMIC_ALLOW_MODESET); EGLAttrib const crtc_filter[] = { EGL_DRM_CRTC_EXT, static_cast(crtc_id), @@ -298,8 +254,6 @@ void mgek::EGLOutput::configure(size_t kms_mode_index) std::string{"Failed to find EGLOutputEXT corresponding to DRM CRTC "} + std::to_string(crtc_id)}); } - - using_saved_crtc = false; } EGLOutputLayerEXT mgek::EGLOutput::output_layer() const @@ -320,7 +274,7 @@ uint32_t mgek::EGLOutput::crtc_id() const return static_cast(crtc_id); } -bool mgek::EGLOutput::queue_atomic_flip(FBHandle const& fb, void const* drm_event_userdata) +int mgek::EGLOutput::atomic_commit(uint64_t fb, const void *drm_event_userdata, uint32_t flags) { auto const width = connector->modes[mode_index].hdisplay; auto const height = connector->modes[mode_index].vdisplay; @@ -328,6 +282,21 @@ bool mgek::EGLOutput::queue_atomic_flip(FBHandle const& fb, void const* drm_even std::unique_ptr request{drmModeAtomicAlloc(), &drmModeAtomicFree}; + if (flags & DRM_MODE_ATOMIC_ALLOW_MODESET) + { + auto _crtc_id = crtc_id(); + mgk::ObjectProperties crtc_props{drm_fd, _crtc_id, DRM_MODE_OBJECT_CRTC}; + + /* Activate the CRTC and set the mode */ + drmModeAtomicAddProperty(request.get(), _crtc_id, crtc_props.id_for("MODE_ID"), mode_id); + drmModeAtomicAddProperty(request.get(), _crtc_id, crtc_props.id_for("ACTIVE"), 1); + + /* Set CRTC for the output */ + auto const connector_id = connector->connector_id; + mgk::ObjectProperties connector_props{drm_fd, connector_id, DRM_MODE_OBJECT_CONNECTOR}; + drmModeAtomicAddProperty(request.get(), connector_id, connector_props.id_for("CRTC_ID"), _crtc_id); + } + /* Source viewport. Coordinates are 16.16 fixed point format */ drmModeAtomicAddProperty(request.get(), plane_id, plane_props->id_for("SRC_X"), 0); drmModeAtomicAddProperty(request.get(), plane_id, plane_props->id_for("SRC_Y"), 0); @@ -345,14 +314,25 @@ bool mgek::EGLOutput::queue_atomic_flip(FBHandle const& fb, void const* drm_even drmModeAtomicAddProperty(request.get(), plane_id, plane_props->id_for("FB_ID"), fb); /* We don't monitor the DRM events (yet), so have no userdata */ - auto ret = drmModeAtomicCommit(drm_fd, request.get(), DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT, const_cast(drm_event_userdata)); + auto ret = drmModeAtomicCommit(drm_fd, request.get(), flags, const_cast(drm_event_userdata)); if (ret != 0) { - BOOST_THROW_EXCEPTION((std::system_error{-ret, std::system_category(), "Failed to commit Atomic KMS state"})); + return ret; } - + using_saved_crtc = false; + return 0; +} + +bool mgek::EGLOutput::queue_atomic_flip(FBHandle const& fb, void const* drm_event_userdata) +{ + int ret = atomic_commit(fb, drm_event_userdata, DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT); + if (ret != 0) + { + BOOST_THROW_EXCEPTION((std::system_error{-ret, std::system_category(), "Failed to commit Atomic KMS state"})); + } + return true; } diff --git a/src/platforms/eglstream-kms/server/egl_output.h b/src/platforms/eglstream-kms/server/egl_output.h index bcec28d5e8..c17350782f 100644 --- a/src/platforms/eglstream-kms/server/egl_output.h +++ b/src/platforms/eglstream-kms/server/egl_output.h @@ -56,6 +56,7 @@ class EGLOutput : public DisplayConfigurationOutput private: void restore_saved_crtc(); + int atomic_commit(uint64_t fb, void const* drm_event_userdata, uint32_t flags); int const drm_fd; @@ -73,6 +74,8 @@ class EGLOutput : public DisplayConfigurationOutput uint32_t plane_id; std::unique_ptr plane_props; + uint32_t mode_id; + int dpms_enum_id; };