mirror of
https://github.com/hyprwm/aquamarine.git
synced 2024-11-17 01:25:59 +01:00
drm: add support for explicit sync
This commit is contained in:
parent
bb8743d9be
commit
330c089cd8
6 changed files with 66 additions and 25 deletions
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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<SOutputMode> customMode;
|
||||
uint32_t drmFormat = DRM_FORMAT_INVALID;
|
||||
Hyprutils::Memory::CSharedPointer<IBuffer> buffer;
|
||||
int64_t explicitInFence = -1, explicitOutFence = -1;
|
||||
};
|
||||
|
||||
const SInternalState& state();
|
||||
|
@ -77,6 +80,8 @@ namespace Aquamarine {
|
|||
void setCustomMode(Hyprutils::Memory::CSharedPointer<SOutputMode> mode);
|
||||
void setFormat(uint32_t drmFormat);
|
||||
void setBuffer(Hyprutils::Memory::CSharedPointer<IBuffer> 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<Hyprutils::Memory::CSharedPointer<SOutputMode>> modes;
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -95,7 +95,21 @@ void Aquamarine::COutputState::setBuffer(Hyprutils::Memory::CSharedPointer<IBuff
|
|||
internalState.committed |= AQ_OUTPUT_STATE_BUFFER;
|
||||
}
|
||||
|
||||
void Aquamarine::COutputState::setExplicitInFence(int64_t fenceFD) {
|
||||
internalState.explicitInFence = fenceFD;
|
||||
internalState.committed |= AQ_OUTPUT_STATE_EXPLICIT_IN_FENCE;
|
||||
}
|
||||
|
||||
void Aquamarine::COutputState::setExplicitOutFence(int64_t fenceFD) {
|
||||
internalState.explicitOutFence = fenceFD;
|
||||
internalState.committed |= AQ_OUTPUT_STATE_EXPLICIT_OUT_FENCE;
|
||||
}
|
||||
|
||||
void Aquamarine::COutputState::onCommit() {
|
||||
internalState.committed = 0;
|
||||
internalState.damage.clear();
|
||||
|
||||
// fences are now used, let's reset them to not confuse ourselves later.
|
||||
internalState.explicitInFence = -1;
|
||||
internalState.explicitOutFence = -1;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue