diff --git a/include/aquamarine/backend/DRM.hpp b/include/aquamarine/backend/DRM.hpp index 6482003..84c93b3 100644 --- a/include/aquamarine/backend/DRM.hpp +++ b/include/aquamarine/backend/DRM.hpp @@ -134,8 +134,9 @@ namespace Aquamarine { uint32_t fb_damage_clips; uint32_t hotspot_x; uint32_t hotspot_y; + uint32_t in_fence_fd; }; - uint32_t props[16] = {0}; + uint32_t props[17] = {0}; }; UDRMPlaneProps props; }; @@ -171,8 +172,9 @@ namespace Aquamarine { uint32_t active; uint32_t mode_id; + uint32_t out_fence_ptr; }; - uint32_t props[6] = {0}; + uint32_t props[7] = {0}; }; UDRMCRTCProps props; }; diff --git a/include/aquamarine/output/Output.hpp b/include/aquamarine/output/Output.hpp index 8bb6e18..c38127f 100644 --- a/include/aquamarine/output/Output.hpp +++ b/include/aquamarine/output/Output.hpp @@ -40,14 +40,16 @@ namespace Aquamarine { class COutputState { public: enum eOutputStateProperties : uint32_t { - AQ_OUTPUT_STATE_DAMAGE = (1 << 0), - AQ_OUTPUT_STATE_ENABLED = (1 << 1), - AQ_OUTPUT_STATE_ADAPTIVE_SYNC = (1 << 2), - AQ_OUTPUT_STATE_PRESENTATION_MODE = (1 << 3), - AQ_OUTPUT_STATE_GAMMA_LUT = (1 << 4), - AQ_OUTPUT_STATE_MODE = (1 << 5), - AQ_OUTPUT_STATE_FORMAT = (1 << 6), - AQ_OUTPUT_STATE_BUFFER = (1 << 7), + AQ_OUTPUT_STATE_DAMAGE = (1 << 0), + AQ_OUTPUT_STATE_ENABLED = (1 << 1), + AQ_OUTPUT_STATE_ADAPTIVE_SYNC = (1 << 2), + AQ_OUTPUT_STATE_PRESENTATION_MODE = (1 << 3), + AQ_OUTPUT_STATE_GAMMA_LUT = (1 << 4), + AQ_OUTPUT_STATE_MODE = (1 << 5), + AQ_OUTPUT_STATE_FORMAT = (1 << 6), + AQ_OUTPUT_STATE_BUFFER = (1 << 7), + AQ_OUTPUT_STATE_EXPLICIT_IN_FENCE = (1 << 8), + AQ_OUTPUT_STATE_EXPLICIT_OUT_FENCE = (1 << 9), }; struct SInternalState { @@ -63,6 +65,7 @@ namespace Aquamarine { Hyprutils::Memory::CSharedPointer customMode; uint32_t drmFormat = DRM_FORMAT_INVALID; Hyprutils::Memory::CSharedPointer buffer; + int64_t explicitInFence = -1, explicitOutFence = -1; }; const SInternalState& state(); @@ -77,6 +80,8 @@ namespace Aquamarine { void setCustomMode(Hyprutils::Memory::CSharedPointer mode); void setFormat(uint32_t drmFormat); void setBuffer(Hyprutils::Memory::CSharedPointer buffer); + void setExplicitInFence(int64_t fenceFD); // -1 removes + void setExplicitOutFence(int64_t fenceFD); // -1 removes private: SInternalState internalState; @@ -113,7 +118,8 @@ namespace Aquamarine { bool nonDesktop = false; eSubpixelMode subpixel = AQ_SUBPIXEL_NONE; bool vrrCapable = false, vrrActive = false; - bool needsFrame = false; + bool needsFrame = false; + bool supportsExplicit = false; // std::vector> modes; diff --git a/src/backend/drm/DRM.cpp b/src/backend/drm/DRM.cpp index c7b4fea..76e0f94 100644 --- a/src/backend/drm/DRM.cpp +++ b/src/backend/drm/DRM.cpp @@ -1045,11 +1045,14 @@ void Aquamarine::SDRMConnector::connect(drmModeConnector* connector) { // TODO: subconnectors - output->make = make; - output->model = model; - output->serial = serial; - output->description = std::format("{} {} {} ({})", make, model, serial, szName); - output->needsFrame = true; + output->make = make; + output->model = model; + output->serial = serial; + output->description = std::format("{} {} {} ({})", make, model, serial, szName); + output->needsFrame = true; + output->supportsExplicit = crtc->props.out_fence_ptr && crtc->primary->props.in_fence_fd; + + backend->backend->log(AQ_LOG_DEBUG, std::format("drm: Explicit sync {}", output->supportsExplicit ? "supported" : "unsupported")); backend->backend->log(AQ_LOG_DEBUG, std::format("drm: Description {}", output->description)); diff --git a/src/backend/drm/Props.cpp b/src/backend/drm/Props.cpp index cd8bac1..e31d4d7 100644 --- a/src/backend/drm/Props.cpp +++ b/src/backend/drm/Props.cpp @@ -36,20 +36,30 @@ static const struct prop_info connector_info[] = { static const struct prop_info crtc_info[] = { #define INDEX(name) (offsetof(SDRMCRTC::UDRMCRTCProps, name) / sizeof(uint32_t)) - {"ACTIVE", INDEX(active)}, {"GAMMA_LUT", INDEX(gamma_lut)}, {"GAMMA_LUT_SIZE", INDEX(gamma_lut_size)}, {"MODE_ID", INDEX(mode_id)}, {"VRR_ENABLED", INDEX(vrr_enabled)}, + {"ACTIVE", INDEX(active)}, {"GAMMA_LUT", INDEX(gamma_lut)}, {"GAMMA_LUT_SIZE", INDEX(gamma_lut_size)}, + {"MODE_ID", INDEX(mode_id)}, {"OUT_FENCE_PTR", INDEX(out_fence_ptr)}, {"VRR_ENABLED", INDEX(vrr_enabled)}, #undef INDEX }; static const struct prop_info plane_info[] = { #define INDEX(name) (offsetof(SDRMPlane::UDRMPlaneProps, name) / sizeof(uint32_t)) - {"CRTC_H", INDEX(crtc_h)}, {"CRTC_ID", INDEX(crtc_id)}, - {"CRTC_W", INDEX(crtc_w)}, {"CRTC_X", INDEX(crtc_x)}, - {"CRTC_Y", INDEX(crtc_y)}, {"FB_DAMAGE_CLIPS", INDEX(fb_damage_clips)}, - {"FB_ID", INDEX(fb_id)}, {"HOTSPOT_X", INDEX(hotspot_x)}, - {"HOTSPOT_Y", INDEX(hotspot_y)}, {"IN_FORMATS", INDEX(in_formats)}, - {"SRC_H", INDEX(src_h)}, {"SRC_W", INDEX(src_w)}, - {"SRC_X", INDEX(src_x)}, {"SRC_Y", INDEX(src_y)}, - {"rotation", INDEX(rotation)}, {"type", INDEX(type)}, + {"CRTC_H", INDEX(crtc_h)}, + {"CRTC_ID", INDEX(crtc_id)}, + {"CRTC_W", INDEX(crtc_w)}, + {"CRTC_X", INDEX(crtc_x)}, + {"CRTC_Y", INDEX(crtc_y)}, + {"FB_DAMAGE_CLIPS", INDEX(fb_damage_clips)}, + {"FB_ID", INDEX(fb_id)}, + {"HOTSPOT_X", INDEX(hotspot_x)}, + {"HOTSPOT_Y", INDEX(hotspot_y)}, + {"IN_FENCE_FD", INDEX(in_fence_fd)}, + {"IN_FORMATS", INDEX(in_formats)}, + {"SRC_H", INDEX(src_h)}, + {"SRC_W", INDEX(src_w)}, + {"SRC_X", INDEX(src_x)}, + {"SRC_Y", INDEX(src_y)}, + {"rotation", INDEX(rotation)}, + {"type", INDEX(type)}, #undef INDEX }; diff --git a/src/backend/drm/impl/Atomic.cpp b/src/backend/drm/impl/Atomic.cpp index fa7d927..e6efec1 100644 --- a/src/backend/drm/impl/Atomic.cpp +++ b/src/backend/drm/impl/Atomic.cpp @@ -100,6 +100,9 @@ void Aquamarine::CDRMAtomicRequest::addConnector(Hyprutils::Memory::CSharedPoint add(connector->crtc->id, connector->crtc->props.active, enable); if (enable) { + if (connector->output->supportsExplicit && STATE.explicitOutFence >= 0) + add(connector->crtc->id, connector->crtc->props.out_fence_ptr, STATE.explicitOutFence); + if (connector->crtc->props.gamma_lut && data.atomic.gammad) add(connector->crtc->id, connector->crtc->props.gamma_lut, data.atomic.gammaLut); @@ -108,6 +111,9 @@ void Aquamarine::CDRMAtomicRequest::addConnector(Hyprutils::Memory::CSharedPoint planeProps(connector->crtc->primary, data.mainFB, connector->crtc->id, {}); + if (connector->output->supportsExplicit && STATE.explicitInFence >= 0) + add(connector->crtc->primary->id, connector->crtc->primary->props.in_fence_fd, STATE.explicitInFence); + if (connector->crtc->primary->props.fb_damage_clips) add(connector->crtc->primary->id, connector->crtc->primary->props.fb_damage_clips, data.atomic.fbDamage); diff --git a/src/output/Output.cpp b/src/output/Output.cpp index 8c12bc9..a8a867c 100644 --- a/src/output/Output.cpp +++ b/src/output/Output.cpp @@ -95,7 +95,21 @@ void Aquamarine::COutputState::setBuffer(Hyprutils::Memory::CSharedPointer