mirror of
https://github.com/hyprwm/aquamarine.git
synced 2024-11-17 03:46:00 +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 fb_damage_clips;
|
||||||
uint32_t hotspot_x;
|
uint32_t hotspot_x;
|
||||||
uint32_t hotspot_y;
|
uint32_t hotspot_y;
|
||||||
|
uint32_t in_fence_fd;
|
||||||
};
|
};
|
||||||
uint32_t props[16] = {0};
|
uint32_t props[17] = {0};
|
||||||
};
|
};
|
||||||
UDRMPlaneProps props;
|
UDRMPlaneProps props;
|
||||||
};
|
};
|
||||||
|
@ -171,8 +172,9 @@ namespace Aquamarine {
|
||||||
|
|
||||||
uint32_t active;
|
uint32_t active;
|
||||||
uint32_t mode_id;
|
uint32_t mode_id;
|
||||||
|
uint32_t out_fence_ptr;
|
||||||
};
|
};
|
||||||
uint32_t props[6] = {0};
|
uint32_t props[7] = {0};
|
||||||
};
|
};
|
||||||
UDRMCRTCProps props;
|
UDRMCRTCProps props;
|
||||||
};
|
};
|
||||||
|
|
|
@ -40,14 +40,16 @@ namespace Aquamarine {
|
||||||
class COutputState {
|
class COutputState {
|
||||||
public:
|
public:
|
||||||
enum eOutputStateProperties : uint32_t {
|
enum eOutputStateProperties : uint32_t {
|
||||||
AQ_OUTPUT_STATE_DAMAGE = (1 << 0),
|
AQ_OUTPUT_STATE_DAMAGE = (1 << 0),
|
||||||
AQ_OUTPUT_STATE_ENABLED = (1 << 1),
|
AQ_OUTPUT_STATE_ENABLED = (1 << 1),
|
||||||
AQ_OUTPUT_STATE_ADAPTIVE_SYNC = (1 << 2),
|
AQ_OUTPUT_STATE_ADAPTIVE_SYNC = (1 << 2),
|
||||||
AQ_OUTPUT_STATE_PRESENTATION_MODE = (1 << 3),
|
AQ_OUTPUT_STATE_PRESENTATION_MODE = (1 << 3),
|
||||||
AQ_OUTPUT_STATE_GAMMA_LUT = (1 << 4),
|
AQ_OUTPUT_STATE_GAMMA_LUT = (1 << 4),
|
||||||
AQ_OUTPUT_STATE_MODE = (1 << 5),
|
AQ_OUTPUT_STATE_MODE = (1 << 5),
|
||||||
AQ_OUTPUT_STATE_FORMAT = (1 << 6),
|
AQ_OUTPUT_STATE_FORMAT = (1 << 6),
|
||||||
AQ_OUTPUT_STATE_BUFFER = (1 << 7),
|
AQ_OUTPUT_STATE_BUFFER = (1 << 7),
|
||||||
|
AQ_OUTPUT_STATE_EXPLICIT_IN_FENCE = (1 << 8),
|
||||||
|
AQ_OUTPUT_STATE_EXPLICIT_OUT_FENCE = (1 << 9),
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SInternalState {
|
struct SInternalState {
|
||||||
|
@ -63,6 +65,7 @@ namespace Aquamarine {
|
||||||
Hyprutils::Memory::CSharedPointer<SOutputMode> customMode;
|
Hyprutils::Memory::CSharedPointer<SOutputMode> customMode;
|
||||||
uint32_t drmFormat = DRM_FORMAT_INVALID;
|
uint32_t drmFormat = DRM_FORMAT_INVALID;
|
||||||
Hyprutils::Memory::CSharedPointer<IBuffer> buffer;
|
Hyprutils::Memory::CSharedPointer<IBuffer> buffer;
|
||||||
|
int64_t explicitInFence = -1, explicitOutFence = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
const SInternalState& state();
|
const SInternalState& state();
|
||||||
|
@ -77,6 +80,8 @@ namespace Aquamarine {
|
||||||
void setCustomMode(Hyprutils::Memory::CSharedPointer<SOutputMode> mode);
|
void setCustomMode(Hyprutils::Memory::CSharedPointer<SOutputMode> mode);
|
||||||
void setFormat(uint32_t drmFormat);
|
void setFormat(uint32_t drmFormat);
|
||||||
void setBuffer(Hyprutils::Memory::CSharedPointer<IBuffer> buffer);
|
void setBuffer(Hyprutils::Memory::CSharedPointer<IBuffer> buffer);
|
||||||
|
void setExplicitInFence(int64_t fenceFD); // -1 removes
|
||||||
|
void setExplicitOutFence(int64_t fenceFD); // -1 removes
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SInternalState internalState;
|
SInternalState internalState;
|
||||||
|
@ -113,7 +118,8 @@ namespace Aquamarine {
|
||||||
bool nonDesktop = false;
|
bool nonDesktop = false;
|
||||||
eSubpixelMode subpixel = AQ_SUBPIXEL_NONE;
|
eSubpixelMode subpixel = AQ_SUBPIXEL_NONE;
|
||||||
bool vrrCapable = false, vrrActive = false;
|
bool vrrCapable = false, vrrActive = false;
|
||||||
bool needsFrame = false;
|
bool needsFrame = false;
|
||||||
|
bool supportsExplicit = false;
|
||||||
|
|
||||||
//
|
//
|
||||||
std::vector<Hyprutils::Memory::CSharedPointer<SOutputMode>> modes;
|
std::vector<Hyprutils::Memory::CSharedPointer<SOutputMode>> modes;
|
||||||
|
|
|
@ -1045,11 +1045,14 @@ void Aquamarine::SDRMConnector::connect(drmModeConnector* connector) {
|
||||||
|
|
||||||
// TODO: subconnectors
|
// TODO: subconnectors
|
||||||
|
|
||||||
output->make = make;
|
output->make = make;
|
||||||
output->model = model;
|
output->model = model;
|
||||||
output->serial = serial;
|
output->serial = serial;
|
||||||
output->description = std::format("{} {} {} ({})", make, model, serial, szName);
|
output->description = std::format("{} {} {} ({})", make, model, serial, szName);
|
||||||
output->needsFrame = true;
|
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));
|
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[] = {
|
static const struct prop_info crtc_info[] = {
|
||||||
#define INDEX(name) (offsetof(SDRMCRTC::UDRMCRTCProps, name) / sizeof(uint32_t))
|
#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
|
#undef INDEX
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct prop_info plane_info[] = {
|
static const struct prop_info plane_info[] = {
|
||||||
#define INDEX(name) (offsetof(SDRMPlane::UDRMPlaneProps, name) / sizeof(uint32_t))
|
#define INDEX(name) (offsetof(SDRMPlane::UDRMPlaneProps, name) / sizeof(uint32_t))
|
||||||
{"CRTC_H", INDEX(crtc_h)}, {"CRTC_ID", INDEX(crtc_id)},
|
{"CRTC_H", INDEX(crtc_h)},
|
||||||
{"CRTC_W", INDEX(crtc_w)}, {"CRTC_X", INDEX(crtc_x)},
|
{"CRTC_ID", INDEX(crtc_id)},
|
||||||
{"CRTC_Y", INDEX(crtc_y)}, {"FB_DAMAGE_CLIPS", INDEX(fb_damage_clips)},
|
{"CRTC_W", INDEX(crtc_w)},
|
||||||
{"FB_ID", INDEX(fb_id)}, {"HOTSPOT_X", INDEX(hotspot_x)},
|
{"CRTC_X", INDEX(crtc_x)},
|
||||||
{"HOTSPOT_Y", INDEX(hotspot_y)}, {"IN_FORMATS", INDEX(in_formats)},
|
{"CRTC_Y", INDEX(crtc_y)},
|
||||||
{"SRC_H", INDEX(src_h)}, {"SRC_W", INDEX(src_w)},
|
{"FB_DAMAGE_CLIPS", INDEX(fb_damage_clips)},
|
||||||
{"SRC_X", INDEX(src_x)}, {"SRC_Y", INDEX(src_y)},
|
{"FB_ID", INDEX(fb_id)},
|
||||||
{"rotation", INDEX(rotation)}, {"type", INDEX(type)},
|
{"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
|
#undef INDEX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -100,6 +100,9 @@ void Aquamarine::CDRMAtomicRequest::addConnector(Hyprutils::Memory::CSharedPoint
|
||||||
add(connector->crtc->id, connector->crtc->props.active, enable);
|
add(connector->crtc->id, connector->crtc->props.active, enable);
|
||||||
|
|
||||||
if (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)
|
if (connector->crtc->props.gamma_lut && data.atomic.gammad)
|
||||||
add(connector->crtc->id, connector->crtc->props.gamma_lut, data.atomic.gammaLut);
|
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, {});
|
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)
|
if (connector->crtc->primary->props.fb_damage_clips)
|
||||||
add(connector->crtc->primary->id, connector->crtc->primary->props.fb_damage_clips, data.atomic.fbDamage);
|
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;
|
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() {
|
void Aquamarine::COutputState::onCommit() {
|
||||||
internalState.committed = 0;
|
internalState.committed = 0;
|
||||||
internalState.damage.clear();
|
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