mirror of
https://github.com/hyprwm/aquamarine.git
synced 2024-12-22 11:39:49 +01:00
drm: misc/atomic fixes
atomic: launches, but mode blobs are broken fixed frame events being signaled too often
This commit is contained in:
parent
55ac96271f
commit
944b0465fa
6 changed files with 66 additions and 53 deletions
|
@ -186,7 +186,13 @@ namespace Aquamarine {
|
|||
bool test = false;
|
||||
drmModeModeInfo modeInfo;
|
||||
|
||||
void calculateMode(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector);
|
||||
struct {
|
||||
uint32_t gammaLut = 0;
|
||||
uint32_t fbDamage = 0;
|
||||
uint32_t modeBlob = 0;
|
||||
} atomic;
|
||||
|
||||
void calculateMode(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector);
|
||||
};
|
||||
|
||||
struct SDRMConnector {
|
||||
|
@ -198,7 +204,7 @@ namespace Aquamarine {
|
|||
Hyprutils::Memory::CSharedPointer<SDRMCRTC> getCurrentCRTC(const drmModeConnector* connector);
|
||||
drmModeModeInfo* getCurrentMode();
|
||||
void parseEDID(std::vector<uint8_t> data);
|
||||
bool commitState(const SDRMConnectorCommitData& data);
|
||||
bool commitState(SDRMConnectorCommitData& data);
|
||||
void applyCommit(const SDRMConnectorCommitData& data);
|
||||
void rollbackCommit(const SDRMConnectorCommitData& data);
|
||||
void onPresent();
|
||||
|
@ -222,14 +228,12 @@ namespace Aquamarine {
|
|||
|
||||
bool isPageFlipPending = false;
|
||||
SDRMPageFlip pendingPageFlip;
|
||||
bool frameEventScheduled = false;
|
||||
|
||||
drmModeModeInfo fallbackModeInfo;
|
||||
|
||||
struct {
|
||||
uint32_t modeID = 0;
|
||||
uint32_t gammaLut = 0;
|
||||
uint32_t fbDamage = 0;
|
||||
bool vrrEnabled = false;
|
||||
bool vrrEnabled = false;
|
||||
} atomic;
|
||||
|
||||
union UDRMConnectorProps {
|
||||
|
@ -256,8 +260,8 @@ namespace Aquamarine {
|
|||
|
||||
class IDRMImplementation {
|
||||
public:
|
||||
virtual bool commit(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, const SDRMConnectorCommitData& data) = 0;
|
||||
virtual bool reset(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector) = 0;
|
||||
virtual bool commit(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, SDRMConnectorCommitData& data) = 0;
|
||||
virtual bool reset(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector) = 0;
|
||||
|
||||
// moving a cursor IIRC is almost instant on most hardware so we don't have to wait for a commit.
|
||||
virtual bool moveCursor(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector) = 0;
|
||||
|
|
|
@ -6,12 +6,12 @@ namespace Aquamarine {
|
|||
class CDRMAtomicImpl : public IDRMImplementation {
|
||||
public:
|
||||
CDRMAtomicImpl(Hyprutils::Memory::CSharedPointer<CDRMBackend> backend_);
|
||||
virtual bool commit(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, const SDRMConnectorCommitData& data);
|
||||
virtual bool commit(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, SDRMConnectorCommitData& data);
|
||||
virtual bool reset(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector);
|
||||
virtual bool moveCursor(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector);
|
||||
|
||||
private:
|
||||
bool prepareConnector(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, const SDRMConnectorCommitData& data);
|
||||
bool prepareConnector(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, SDRMConnectorCommitData& data);
|
||||
|
||||
Hyprutils::Memory::CWeakPointer<CDRMBackend> backend;
|
||||
|
||||
|
@ -23,13 +23,13 @@ namespace Aquamarine {
|
|||
CDRMAtomicRequest(Hyprutils::Memory::CWeakPointer<CDRMBackend> backend);
|
||||
~CDRMAtomicRequest();
|
||||
|
||||
void addConnector(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, const SDRMConnectorCommitData& data);
|
||||
void addConnector(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, SDRMConnectorCommitData& data);
|
||||
bool commit(uint32_t flagssss);
|
||||
void add(uint32_t id, uint32_t prop, uint64_t val);
|
||||
void planeProps(Hyprutils::Memory::CSharedPointer<SDRMPlane> plane, Hyprutils::Memory::CSharedPointer<CDRMFB> fb, uint32_t crtc, Hyprutils::Math::Vector2D pos);
|
||||
|
||||
void rollback();
|
||||
void apply();
|
||||
void rollback(SDRMConnectorCommitData& data);
|
||||
void apply(SDRMConnectorCommitData& data);
|
||||
|
||||
bool failed = false;
|
||||
|
||||
|
|
|
@ -6,14 +6,14 @@ namespace Aquamarine {
|
|||
class CDRMLegacyImpl : public IDRMImplementation {
|
||||
public:
|
||||
CDRMLegacyImpl(Hyprutils::Memory::CSharedPointer<CDRMBackend> backend_);
|
||||
virtual bool commit(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, const SDRMConnectorCommitData& data);
|
||||
virtual bool commit(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, SDRMConnectorCommitData& data);
|
||||
virtual bool reset(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector);
|
||||
virtual bool moveCursor(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector);
|
||||
|
||||
private:
|
||||
|
||||
bool commitInternal(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, const SDRMConnectorCommitData& data);
|
||||
bool testInternal(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, const SDRMConnectorCommitData& data);
|
||||
bool commitInternal(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, SDRMConnectorCommitData& data);
|
||||
bool testInternal(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, SDRMConnectorCommitData& data);
|
||||
|
||||
Hyprutils::Memory::CWeakPointer<CDRMBackend> backend;
|
||||
};
|
||||
|
|
|
@ -528,7 +528,7 @@ static void handlePF(int fd, unsigned seq, unsigned tv_sec, unsigned tv_usec, un
|
|||
.flags = flags,
|
||||
});
|
||||
|
||||
if (BACKEND->sessionActive())
|
||||
if (BACKEND->sessionActive() && !pageFlip->connector->frameEventScheduled)
|
||||
pageFlip->connector->output->events.frame.emit();
|
||||
}
|
||||
|
||||
|
@ -902,7 +902,7 @@ void Aquamarine::SDRMConnector::disconnect() {
|
|||
status = DRM_MODE_DISCONNECTED;
|
||||
}
|
||||
|
||||
bool Aquamarine::SDRMConnector::commitState(const SDRMConnectorCommitData& data) {
|
||||
bool Aquamarine::SDRMConnector::commitState(SDRMConnectorCommitData& data) {
|
||||
const bool ok = backend->impl->commit(self.lock(), data);
|
||||
|
||||
if (ok && !data.test)
|
||||
|
@ -1102,10 +1102,17 @@ void Aquamarine::CDRMOutput::moveCursor(const Vector2D& coord) {
|
|||
}
|
||||
|
||||
void Aquamarine::CDRMOutput::scheduleFrame() {
|
||||
if (connector->isPageFlipPending)
|
||||
if (connector->isPageFlipPending || connector->frameEventScheduled)
|
||||
return;
|
||||
|
||||
backend->idleCallbacks.emplace_back([this]() { events.frame.emit(); });
|
||||
connector->frameEventScheduled = true;
|
||||
|
||||
backend->idleCallbacks.emplace_back([this]() {
|
||||
connector->frameEventScheduled = false;
|
||||
if (connector->isPageFlipPending)
|
||||
return;
|
||||
events.frame.emit();
|
||||
});
|
||||
}
|
||||
|
||||
Vector2D Aquamarine::CDRMOutput::cursorPlaneSize() {
|
||||
|
|
|
@ -67,7 +67,7 @@ void Aquamarine::CDRMAtomicRequest::planeProps(Hyprutils::Memory::CSharedPointer
|
|||
add(plane->id, plane->props.crtc_y, (uint64_t)pos.y);
|
||||
}
|
||||
|
||||
void Aquamarine::CDRMAtomicRequest::addConnector(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, const SDRMConnectorCommitData& data) {
|
||||
void Aquamarine::CDRMAtomicRequest::addConnector(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, SDRMConnectorCommitData& data) {
|
||||
const auto& STATE = connector->output->state->state();
|
||||
const bool enable = STATE.enabled && data.mainFB;
|
||||
|
||||
|
@ -87,7 +87,7 @@ void Aquamarine::CDRMAtomicRequest::addConnector(Hyprutils::Memory::CSharedPoint
|
|||
if (data.modeset && enable && connector->props.max_bpc && connector->maxBpcBounds.at(1))
|
||||
add(connector->id, connector->props.max_bpc, 8); // FIXME: this isnt always 8
|
||||
|
||||
add(connector->crtc->id, connector->crtc->props.mode_id, connector->atomic.modeID);
|
||||
// add(connector->crtc->id, connector->crtc->props.mode_id, data.atomic.modeBlob);
|
||||
add(connector->crtc->id, connector->crtc->props.active, enable);
|
||||
|
||||
if (enable) {
|
||||
|
@ -98,7 +98,7 @@ void Aquamarine::CDRMAtomicRequest::addConnector(Hyprutils::Memory::CSharedPoint
|
|||
planeProps(connector->crtc->primary, data.mainFB, connector->crtc->id, {});
|
||||
|
||||
if (connector->crtc->primary->props.fb_damage_clips)
|
||||
add(connector->crtc->primary->id, connector->crtc->primary->props.fb_damage_clips, connector->atomic.fbDamage);
|
||||
add(connector->crtc->primary->id, connector->crtc->primary->props.fb_damage_clips, data.atomic.fbDamage);
|
||||
|
||||
if (connector->crtc->cursor) {
|
||||
if (!connector->output->cursorVisible)
|
||||
|
@ -169,38 +169,44 @@ void Aquamarine::CDRMAtomicRequest::rollbackBlob(uint32_t* current, uint32_t nex
|
|||
destroyBlob(next);
|
||||
}
|
||||
|
||||
void Aquamarine::CDRMAtomicRequest::rollback() {
|
||||
void Aquamarine::CDRMAtomicRequest::rollback(SDRMConnectorCommitData& data) {
|
||||
if (!conn)
|
||||
return;
|
||||
|
||||
conn->crtc->atomic.ownModeID = true;
|
||||
rollbackBlob(&conn->crtc->atomic.modeID, conn->atomic.modeID);
|
||||
rollbackBlob(&conn->crtc->atomic.modeID, data.atomic.modeBlob);
|
||||
// TODO: gamma
|
||||
//rollbackBlob(&conn->crtc->atomic.gammaLut, conn->atomic.gammaLut);
|
||||
destroyBlob(conn->atomic.fbDamage);
|
||||
destroyBlob(data.atomic.fbDamage);
|
||||
}
|
||||
|
||||
void Aquamarine::CDRMAtomicRequest::apply() {
|
||||
void Aquamarine::CDRMAtomicRequest::apply(SDRMConnectorCommitData& data) {
|
||||
if (!conn)
|
||||
return;
|
||||
|
||||
if (!conn->crtc->atomic.ownModeID)
|
||||
conn->crtc->atomic.modeID = 0;
|
||||
|
||||
conn->crtc->atomic.ownModeID = true;
|
||||
commitBlob(&conn->crtc->atomic.modeID, conn->atomic.modeID);
|
||||
commitBlob(&conn->crtc->atomic.modeID, data.atomic.modeBlob);
|
||||
// TODO: gamma
|
||||
//commitBlob(&conn->crtc->atomic.gammaLut, conn->atomic.gammaLut);
|
||||
destroyBlob(conn->atomic.fbDamage);
|
||||
destroyBlob(data.atomic.fbDamage);
|
||||
}
|
||||
|
||||
Aquamarine::CDRMAtomicImpl::CDRMAtomicImpl(Hyprutils::Memory::CSharedPointer<CDRMBackend> backend_) : backend(backend_) {
|
||||
;
|
||||
}
|
||||
|
||||
bool Aquamarine::CDRMAtomicImpl::prepareConnector(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, const SDRMConnectorCommitData& data) {
|
||||
bool Aquamarine::CDRMAtomicImpl::prepareConnector(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, SDRMConnectorCommitData& data) {
|
||||
const auto& STATE = connector->output->state->state();
|
||||
const bool enable = STATE.enabled;
|
||||
|
||||
if (data.modeset) {
|
||||
if (!enable)
|
||||
connector->atomic.modeID = 0;
|
||||
data.atomic.modeBlob = 0;
|
||||
else {
|
||||
if (drmModeCreatePropertyBlob(connector->backend->gpu->fd, (drmModeModeInfo*)&data.modeInfo, sizeof(drmModeModeInfo), &connector->atomic.modeID)) {
|
||||
if (drmModeCreatePropertyBlob(connector->backend->gpu->fd, (drmModeModeInfo*)&data.modeInfo, sizeof(drmModeModeInfo), &data.atomic.modeBlob)) {
|
||||
connector->backend->backend->log(AQ_LOG_ERROR, "atomic drm: failed to create a modeset blob");
|
||||
return false;
|
||||
}
|
||||
|
@ -211,10 +217,10 @@ bool Aquamarine::CDRMAtomicImpl::prepareConnector(Hyprutils::Memory::CSharedPoin
|
|||
|
||||
if (STATE.committed & COutputState::AQ_OUTPUT_STATE_DAMAGE && connector->crtc->primary->props.fb_damage_clips) {
|
||||
if (STATE.damage.empty())
|
||||
connector->atomic.fbDamage = 0;
|
||||
data.atomic.fbDamage = 0;
|
||||
else {
|
||||
std::vector<pixman_box32_t> rects = STATE.damage.getRects();
|
||||
if (drmModeCreatePropertyBlob(connector->backend->gpu->fd, rects.data(), sizeof(pixman_box32_t) * rects.size(), &connector->atomic.fbDamage)) {
|
||||
if (drmModeCreatePropertyBlob(connector->backend->gpu->fd, rects.data(), sizeof(pixman_box32_t) * rects.size(), &data.atomic.fbDamage)) {
|
||||
connector->backend->backend->log(AQ_LOG_ERROR, "atomic drm: failed to create a damage blob");
|
||||
return false;
|
||||
}
|
||||
|
@ -224,7 +230,7 @@ bool Aquamarine::CDRMAtomicImpl::prepareConnector(Hyprutils::Memory::CSharedPoin
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Aquamarine::CDRMAtomicImpl::commit(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, const SDRMConnectorCommitData& data) {
|
||||
bool Aquamarine::CDRMAtomicImpl::commit(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, SDRMConnectorCommitData& data) {
|
||||
if (!prepareConnector(connector, data))
|
||||
return false;
|
||||
|
||||
|
@ -242,10 +248,11 @@ bool Aquamarine::CDRMAtomicImpl::commit(Hyprutils::Memory::CSharedPointer<SDRMCo
|
|||
|
||||
const bool ok = request.commit(flags);
|
||||
|
||||
if (ok)
|
||||
request.apply();
|
||||
else
|
||||
request.rollback();
|
||||
if (ok) {
|
||||
request.apply(data);
|
||||
connector->isPageFlipPending = true;
|
||||
} else
|
||||
request.rollback(data);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
@ -273,11 +280,8 @@ bool Aquamarine::CDRMAtomicImpl::moveCursor(Hyprutils::Memory::CSharedPointer<SD
|
|||
if (!connector->output->cursorVisible || !connector->output->state->state().enabled || !connector->crtc || !connector->crtc->cursor)
|
||||
return true;
|
||||
|
||||
CDRMAtomicRequest request(backend);
|
||||
|
||||
request.planeProps(connector->crtc->cursor, connector->crtc->cursor->front, connector->crtc->id, connector->output->cursorPos - connector->output->cursorHotspot);
|
||||
|
||||
return request.commit(DRM_MODE_ATOMIC_NONBLOCK);
|
||||
connector->output->needsFrame = true;
|
||||
connector->output->scheduleFrame();
|
||||
|
||||
return true;
|
||||
}
|
|
@ -14,18 +14,16 @@ Aquamarine::CDRMLegacyImpl::CDRMLegacyImpl(Hyprutils::Memory::CSharedPointer<CDR
|
|||
}
|
||||
|
||||
bool Aquamarine::CDRMLegacyImpl::moveCursor(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector) {
|
||||
Vector2D cursorPos = connector->output->cursorPos;
|
||||
if (int ret2 = drmModeMoveCursor(connector->backend->gpu->fd, connector->crtc->id, cursorPos.x, cursorPos.y)) {
|
||||
connector->backend->backend->log(AQ_LOG_ERROR, std::format("legacy drm: drmModeMoveCursor failed: {}", strerror(-ret2)));
|
||||
return false;
|
||||
}
|
||||
if (!connector->output->cursorVisible || !connector->output->state->state().enabled || !connector->crtc || !connector->crtc->cursor)
|
||||
return true;
|
||||
|
||||
connector->backend->backend->log(AQ_LOG_DEBUG, "legacy drm: cursor move");
|
||||
connector->output->needsFrame = true;
|
||||
connector->output->scheduleFrame();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Aquamarine::CDRMLegacyImpl::commitInternal(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, const SDRMConnectorCommitData& data) {
|
||||
bool Aquamarine::CDRMLegacyImpl::commitInternal(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, SDRMConnectorCommitData& data) {
|
||||
const auto& STATE = connector->output->state->state();
|
||||
SP<CDRMFB> mainFB;
|
||||
bool enable = STATE.enabled;
|
||||
|
@ -141,11 +139,11 @@ bool Aquamarine::CDRMLegacyImpl::commitInternal(Hyprutils::Memory::CSharedPointe
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Aquamarine::CDRMLegacyImpl::testInternal(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, const SDRMConnectorCommitData& data) {
|
||||
bool Aquamarine::CDRMLegacyImpl::testInternal(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, SDRMConnectorCommitData& data) {
|
||||
return true; // TODO: lol
|
||||
}
|
||||
|
||||
bool Aquamarine::CDRMLegacyImpl::commit(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, const SDRMConnectorCommitData& data) {
|
||||
bool Aquamarine::CDRMLegacyImpl::commit(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, SDRMConnectorCommitData& data) {
|
||||
if (!testInternal(connector, data))
|
||||
return false;
|
||||
|
||||
|
|
Loading…
Reference in a new issue