backends/drm: port away from mode indices
They're error prone and don't really work for changing modes. Having a current mode in DrmConnector also doesn't work well together with the transactional style of how DrmPipeline operates
This commit is contained in:
parent
03efdabf26
commit
e8eb55ad2e
6 changed files with 74 additions and 109 deletions
|
@ -23,6 +23,22 @@
|
||||||
namespace KWin
|
namespace KWin
|
||||||
{
|
{
|
||||||
|
|
||||||
|
static bool checkIfEqual(const drmModeModeInfo *one, const drmModeModeInfo *two)
|
||||||
|
{
|
||||||
|
return one->clock == two->clock
|
||||||
|
&& one->hdisplay == two->hdisplay
|
||||||
|
&& one->hsync_start == two->hsync_start
|
||||||
|
&& one->hsync_end == two->hsync_end
|
||||||
|
&& one->htotal == two->htotal
|
||||||
|
&& one->hskew == two->hskew
|
||||||
|
&& one->vdisplay == two->vdisplay
|
||||||
|
&& one->vsync_start == two->vsync_start
|
||||||
|
&& one->vsync_end == two->vsync_end
|
||||||
|
&& one->vtotal == two->vtotal
|
||||||
|
&& one->vscan == two->vscan
|
||||||
|
&& one->vrefresh == two->vrefresh;
|
||||||
|
}
|
||||||
|
|
||||||
static quint64 refreshRateForMode(_drmModeModeInfo *m)
|
static quint64 refreshRateForMode(_drmModeModeInfo *m)
|
||||||
{
|
{
|
||||||
// Calculate higher precision (mHz) refresh rate
|
// Calculate higher precision (mHz) refresh rate
|
||||||
|
@ -81,6 +97,11 @@ uint32_t DrmConnectorMode::blobId()
|
||||||
return m_blobId;
|
return m_blobId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DrmConnectorMode::operator==(const DrmConnectorMode &otherMode)
|
||||||
|
{
|
||||||
|
return checkIfEqual(&m_nativeMode, &otherMode.m_nativeMode);
|
||||||
|
}
|
||||||
|
|
||||||
DrmConnector::DrmConnector(DrmGpu *gpu, uint32_t connectorId)
|
DrmConnector::DrmConnector(DrmGpu *gpu, uint32_t connectorId)
|
||||||
: DrmObject(gpu, connectorId, {
|
: DrmObject(gpu, connectorId, {
|
||||||
PropertyDefinition(QByteArrayLiteral("CRTC_ID"), Requirement::Required),
|
PropertyDefinition(QByteArrayLiteral("CRTC_ID"), Requirement::Required),
|
||||||
|
@ -124,11 +145,6 @@ DrmConnector::DrmConnector(DrmGpu *gpu, uint32_t connectorId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DrmConnector::~DrmConnector()
|
|
||||||
{
|
|
||||||
qDeleteAll(m_modes);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DrmConnector::init()
|
bool DrmConnector::init()
|
||||||
{
|
{
|
||||||
return m_conn && initProps();
|
return m_conn && initProps();
|
||||||
|
@ -197,51 +213,17 @@ QSize DrmConnector::physicalSize() const
|
||||||
return m_physicalSize;
|
return m_physicalSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
DrmConnectorMode *DrmConnector::currentMode() const
|
QVector<QSharedPointer<DrmConnectorMode>> DrmConnector::modes() const
|
||||||
{
|
|
||||||
return m_modes[m_modeIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
int DrmConnector::currentModeIndex() const
|
|
||||||
{
|
|
||||||
return m_modeIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
QVector<DrmConnectorMode *> DrmConnector::modes() const
|
|
||||||
{
|
{
|
||||||
return m_modes;
|
return m_modes;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrmConnector::setModeIndex(int index)
|
QSharedPointer<DrmConnectorMode> DrmConnector::findMode(const drmModeModeInfo &modeInfo) const
|
||||||
{
|
{
|
||||||
m_modeIndex = index;
|
const auto it = std::find_if(m_modes.constBegin(), m_modes.constEnd(), [&modeInfo](const auto &mode) {
|
||||||
}
|
return checkIfEqual(mode->nativeMode(), &modeInfo);
|
||||||
|
});
|
||||||
static bool checkIfEqual(const drmModeModeInfo *one, const drmModeModeInfo *two)
|
return it == m_modes.constEnd() ? nullptr : *it;
|
||||||
{
|
|
||||||
return one->clock == two->clock
|
|
||||||
&& one->hdisplay == two->hdisplay
|
|
||||||
&& one->hsync_start == two->hsync_start
|
|
||||||
&& one->hsync_end == two->hsync_end
|
|
||||||
&& one->htotal == two->htotal
|
|
||||||
&& one->hskew == two->hskew
|
|
||||||
&& one->vdisplay == two->vdisplay
|
|
||||||
&& one->vsync_start == two->vsync_start
|
|
||||||
&& one->vsync_end == two->vsync_end
|
|
||||||
&& one->vtotal == two->vtotal
|
|
||||||
&& one->vscan == two->vscan
|
|
||||||
&& one->vrefresh == two->vrefresh;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DrmConnector::findCurrentMode(drmModeModeInfo currentMode)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < m_modes.count(); i++) {
|
|
||||||
if (checkIfEqual(m_modes[i]->nativeMode(), ¤tMode)) {
|
|
||||||
m_modeIndex = i;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_modeIndex = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractWaylandOutput::SubPixel DrmConnector::subpixel() const
|
AbstractWaylandOutput::SubPixel DrmConnector::subpixel() const
|
||||||
|
@ -322,12 +304,11 @@ bool DrmConnector::needsModeset() const
|
||||||
|
|
||||||
void DrmConnector::updateModes()
|
void DrmConnector::updateModes()
|
||||||
{
|
{
|
||||||
qDeleteAll(m_modes);
|
|
||||||
m_modes.clear();
|
m_modes.clear();
|
||||||
|
|
||||||
// reload modes
|
// reload modes
|
||||||
for (int i = 0; i < m_conn->count_modes; i++) {
|
for (int i = 0; i < m_conn->count_modes; i++) {
|
||||||
m_modes.append(new DrmConnectorMode(this, m_conn->modes[i]));
|
m_modes.append(QSharedPointer<DrmConnectorMode>::create(this, m_conn->modes[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,6 +389,9 @@ bool DrmConnector::updateProperties()
|
||||||
|
|
||||||
// init modes
|
// init modes
|
||||||
updateModes();
|
updateModes();
|
||||||
|
if (!m_modes.isEmpty() && !m_pipeline->pending.mode) {
|
||||||
|
m_pipeline->pending.mode = m_modes.constFirst();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,8 @@ public:
|
||||||
QSize size() const;
|
QSize size() const;
|
||||||
uint32_t refreshRate() const;
|
uint32_t refreshRate() const;
|
||||||
|
|
||||||
|
bool operator==(const DrmConnectorMode &otherMode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DrmConnector *m_connector;
|
DrmConnector *m_connector;
|
||||||
drmModeModeInfo m_nativeMode;
|
drmModeModeInfo m_nativeMode;
|
||||||
|
@ -53,7 +55,6 @@ class DrmConnector : public DrmObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DrmConnector(DrmGpu *gpu, uint32_t connectorId);
|
DrmConnector(DrmGpu *gpu, uint32_t connectorId);
|
||||||
~DrmConnector() override;
|
|
||||||
|
|
||||||
enum class PropertyIndex : uint32_t {
|
enum class PropertyIndex : uint32_t {
|
||||||
CrtcId = 0,
|
CrtcId = 0,
|
||||||
|
@ -97,11 +98,8 @@ public:
|
||||||
QString modelName() const;
|
QString modelName() const;
|
||||||
QSize physicalSize() const;
|
QSize physicalSize() const;
|
||||||
|
|
||||||
DrmConnectorMode *currentMode() const;
|
QVector<QSharedPointer<DrmConnectorMode>> modes() const;
|
||||||
int currentModeIndex() const;
|
QSharedPointer<DrmConnectorMode> findMode(const drmModeModeInfo &modeInfo) const;
|
||||||
QVector<DrmConnectorMode *> modes() const;
|
|
||||||
void setModeIndex(int index);
|
|
||||||
void findCurrentMode(drmModeModeInfo currentMode);
|
|
||||||
void updateModes();
|
void updateModes();
|
||||||
|
|
||||||
AbstractWaylandOutput::SubPixel subpixel() const;
|
AbstractWaylandOutput::SubPixel subpixel() const;
|
||||||
|
@ -118,8 +116,7 @@ private:
|
||||||
DrmScopedPointer<drmModeConnector> m_conn;
|
DrmScopedPointer<drmModeConnector> m_conn;
|
||||||
Edid m_edid;
|
Edid m_edid;
|
||||||
QSize m_physicalSize = QSize(-1, -1);
|
QSize m_physicalSize = QSize(-1, -1);
|
||||||
QVector<DrmConnectorMode *> m_modes;
|
QVector<QSharedPointer<DrmConnectorMode>> m_modes;
|
||||||
int m_modeIndex = 0;
|
|
||||||
uint32_t m_possibleCrtcs = 0;
|
uint32_t m_possibleCrtcs = 0;
|
||||||
|
|
||||||
friend QDebug& operator<<(QDebug& s, const KWin::DrmConnector *obj);
|
friend QDebug& operator<<(QDebug& s, const KWin::DrmConnector *obj);
|
||||||
|
|
|
@ -46,8 +46,8 @@ DrmOutput::DrmOutput(DrmPipeline *pipeline)
|
||||||
, m_connector(pipeline->connector())
|
, m_connector(pipeline->connector())
|
||||||
{
|
{
|
||||||
m_pipeline->setOutput(this);
|
m_pipeline->setOutput(this);
|
||||||
auto conn = m_pipeline->connector();
|
const auto conn = m_pipeline->connector();
|
||||||
m_renderLoop->setRefreshRate(conn->currentMode()->refreshRate());
|
m_renderLoop->setRefreshRate(m_pipeline->pending.mode->refreshRate());
|
||||||
setSubPixelInternal(conn->subpixel());
|
setSubPixelInternal(conn->subpixel());
|
||||||
setInternal(conn->isInternal());
|
setInternal(conn->isInternal());
|
||||||
setCapabilityInternal(DrmOutput::Capability::Dpms);
|
setCapabilityInternal(DrmOutput::Capability::Dpms);
|
||||||
|
@ -177,13 +177,13 @@ QVector<AbstractWaylandOutput::Mode> DrmOutput::getModes() const
|
||||||
{
|
{
|
||||||
bool modeFound = false;
|
bool modeFound = false;
|
||||||
QVector<Mode> modes;
|
QVector<Mode> modes;
|
||||||
auto conn = m_pipeline->connector();
|
const auto modelist = m_pipeline->connector()->modes();
|
||||||
QVector<DrmConnectorMode *> modelist = conn->modes();
|
|
||||||
|
|
||||||
modes.reserve(modelist.count());
|
modes.reserve(modelist.count());
|
||||||
for (int i = 0; i < modelist.count(); ++i) {
|
for (int i = 0; i < modelist.count(); ++i) {
|
||||||
Mode mode;
|
Mode mode;
|
||||||
if (i == conn->currentModeIndex()) {
|
// compare the actual mode objects, not the pointers!
|
||||||
|
if (*modelist[i] == *m_pipeline->pending.mode) {
|
||||||
mode.flags |= ModeFlag::Current;
|
mode.flags |= ModeFlag::Current;
|
||||||
modeFound = true;
|
modeFound = true;
|
||||||
}
|
}
|
||||||
|
@ -298,31 +298,21 @@ DrmPlane::Transformations outputToPlaneTransform(DrmOutput::Transform transform)
|
||||||
|
|
||||||
void DrmOutput::updateModes()
|
void DrmOutput::updateModes()
|
||||||
{
|
{
|
||||||
auto conn = m_pipeline->connector();
|
m_pipeline->connector()->updateModes();
|
||||||
conn->updateModes();
|
setModes(getModes());
|
||||||
|
if (m_pipeline->pending.crtc) {
|
||||||
const auto modes = getModes();
|
const auto currentMode = m_pipeline->connector()->findMode(m_pipeline->pending.crtc->queryCurrentMode());
|
||||||
setModes(modes);
|
if (currentMode != m_pipeline->pending.mode) {
|
||||||
|
// DrmConnector::findCurrentMode might fail
|
||||||
auto it = std::find_if(modes.constBegin(), modes.constEnd(),
|
m_pipeline->pending.mode = currentMode ? currentMode : m_pipeline->connector()->modes().constFirst();
|
||||||
[](const AbstractWaylandOutput::Mode &mode){
|
if (DrmPipeline::commitPipelines(m_gpu->pipelines(), DrmPipeline::CommitMode::Test)) {
|
||||||
return mode.flags.testFlag(ModeFlag::Current);
|
m_pipeline->applyPendingChanges();
|
||||||
}
|
setCurrentModeInternal(m_pipeline->pending.mode->size(), m_pipeline->pending.mode->refreshRate());
|
||||||
);
|
m_renderLoop->setRefreshRate(m_pipeline->pending.mode->refreshRate());
|
||||||
Q_ASSERT(it != modes.constEnd());
|
} else {
|
||||||
AbstractWaylandOutput::Mode mode = *it;
|
qCWarning(KWIN_DRM) << "Setting changed mode failed!";
|
||||||
|
m_pipeline->revertPendingChanges();
|
||||||
// mode changed
|
}
|
||||||
if (mode.size != modeSize() || mode.refreshRate != refreshRate()) {
|
|
||||||
m_pipeline->pending.modeIndex = mode.id;
|
|
||||||
if (DrmPipeline::commitPipelines({m_pipeline}, DrmPipeline::CommitMode::Test)) {
|
|
||||||
m_pipeline->applyPendingChanges();
|
|
||||||
auto mode = m_pipeline->connector()->currentMode();
|
|
||||||
setCurrentModeInternal(mode->size(), mode->refreshRate());
|
|
||||||
m_renderLoop->setRefreshRate(mode->refreshRate());
|
|
||||||
} else {
|
|
||||||
qCWarning(KWIN_DRM) << "Setting changed mode failed!";
|
|
||||||
m_pipeline->revertPendingChanges();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -409,21 +399,17 @@ bool DrmOutput::queueChanges(const WaylandOutputConfig &config)
|
||||||
static bool valid;
|
static bool valid;
|
||||||
static int envOnlySoftwareRotations = qEnvironmentVariableIntValue("KWIN_DRM_SW_ROTATIONS_ONLY", &valid) == 1 || !valid;
|
static int envOnlySoftwareRotations = qEnvironmentVariableIntValue("KWIN_DRM_SW_ROTATIONS_ONLY", &valid) == 1 || !valid;
|
||||||
|
|
||||||
auto props = config.constChangeSet(this);
|
const auto props = config.constChangeSet(this);
|
||||||
m_pipeline->pending.active = props->enabled;
|
m_pipeline->pending.active = props->enabled;
|
||||||
auto modelist = m_connector->modes();
|
const auto modelist = m_connector->modes();
|
||||||
int index = -1;
|
const auto it = std::find_if(modelist.begin(), modelist.end(), [&props](const auto &mode) {
|
||||||
for (int i = 0; i < modelist.size(); i++) {
|
return mode->size() == props->modeSize && mode->refreshRate() == props->refreshRate;
|
||||||
if (modelist[i]->size() == props->modeSize && modelist[i]->refreshRate() == props->refreshRate) {
|
});
|
||||||
index = i;
|
if (it == modelist.end()) {
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (index == -1) {
|
|
||||||
qCWarning(KWIN_DRM).nospace() << "Could not find mode " << props->modeSize << "@" << props->refreshRate << " for output " << this;
|
qCWarning(KWIN_DRM).nospace() << "Could not find mode " << props->modeSize << "@" << props->refreshRate << " for output " << this;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_pipeline->pending.modeIndex = index;
|
m_pipeline->pending.mode = *it;
|
||||||
m_pipeline->pending.overscan = props->overscan;
|
m_pipeline->pending.overscan = props->overscan;
|
||||||
m_pipeline->pending.rgbRange = props->rgbRange;
|
m_pipeline->pending.rgbRange = props->rgbRange;
|
||||||
m_pipeline->pending.sourceTransformation = outputToPlaneTransform(props->transform);
|
m_pipeline->pending.sourceTransformation = outputToPlaneTransform(props->transform);
|
||||||
|
@ -448,8 +434,7 @@ void DrmOutput::applyQueuedChanges(const WaylandOutputConfig &config)
|
||||||
setScale(props->scale);
|
setScale(props->scale);
|
||||||
setTransformInternal(props->transform);
|
setTransformInternal(props->transform);
|
||||||
|
|
||||||
m_connector->setModeIndex(m_pipeline->pending.modeIndex);
|
const auto &mode = m_pipeline->pending.mode;
|
||||||
auto mode = m_connector->currentMode();
|
|
||||||
setCurrentModeInternal(mode->size(), mode->refreshRate());
|
setCurrentModeInternal(mode->size(), mode->refreshRate());
|
||||||
m_renderLoop->setRefreshRate(mode->refreshRate());
|
m_renderLoop->setRefreshRate(mode->refreshRate());
|
||||||
setOverscanInternal(m_pipeline->pending.overscan);
|
setOverscanInternal(m_pipeline->pending.overscan);
|
||||||
|
|
|
@ -191,7 +191,7 @@ bool DrmPipeline::populateAtomicValues(drmModeAtomicReq *req, uint32_t &flags)
|
||||||
if (pending.crtc) {
|
if (pending.crtc) {
|
||||||
pending.crtc->setPending(DrmCrtc::PropertyIndex::VrrEnabled, pending.syncMode == RenderLoopPrivate::SyncMode::Adaptive);
|
pending.crtc->setPending(DrmCrtc::PropertyIndex::VrrEnabled, pending.syncMode == RenderLoopPrivate::SyncMode::Adaptive);
|
||||||
pending.crtc->setPending(DrmCrtc::PropertyIndex::Gamma_LUT, pending.gamma ? pending.gamma->blobId() : 0);
|
pending.crtc->setPending(DrmCrtc::PropertyIndex::Gamma_LUT, pending.gamma ? pending.gamma->blobId() : 0);
|
||||||
auto modeSize = m_connector->modes().at(pending.modeIndex)->size();
|
const auto modeSize = pending.mode->size();
|
||||||
pending.crtc->primaryPlane()->set(QPoint(0, 0), m_primaryBuffer ? m_primaryBuffer->size() : bufferSize(), QPoint(0, 0), modeSize);
|
pending.crtc->primaryPlane()->set(QPoint(0, 0), m_primaryBuffer ? m_primaryBuffer->size() : bufferSize(), QPoint(0, 0), modeSize);
|
||||||
pending.crtc->primaryPlane()->setBuffer(activePending() ? m_primaryBuffer.get() : nullptr);
|
pending.crtc->primaryPlane()->setBuffer(activePending() ? m_primaryBuffer.get() : nullptr);
|
||||||
|
|
||||||
|
@ -224,7 +224,6 @@ void DrmPipeline::prepareAtomicModeset()
|
||||||
m_connector->setPending(DrmConnector::PropertyIndex::CrtcId, 0);
|
m_connector->setPending(DrmConnector::PropertyIndex::CrtcId, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto mode = m_connector->modes().at(pending.modeIndex);
|
|
||||||
|
|
||||||
m_connector->setPending(DrmConnector::PropertyIndex::CrtcId, activePending() ? pending.crtc->id() : 0);
|
m_connector->setPending(DrmConnector::PropertyIndex::CrtcId, activePending() ? pending.crtc->id() : 0);
|
||||||
if (const auto &prop = m_connector->getProp(DrmConnector::PropertyIndex::Broadcast_RGB)) {
|
if (const auto &prop = m_connector->getProp(DrmConnector::PropertyIndex::Broadcast_RGB)) {
|
||||||
|
@ -235,7 +234,7 @@ void DrmPipeline::prepareAtomicModeset()
|
||||||
}
|
}
|
||||||
|
|
||||||
pending.crtc->setPending(DrmCrtc::PropertyIndex::Active, activePending());
|
pending.crtc->setPending(DrmCrtc::PropertyIndex::Active, activePending());
|
||||||
pending.crtc->setPending(DrmCrtc::PropertyIndex::ModeId, activePending() ? mode->blobId() : 0);
|
pending.crtc->setPending(DrmCrtc::PropertyIndex::ModeId, activePending() ? pending.mode->blobId() : 0);
|
||||||
|
|
||||||
pending.crtc->primaryPlane()->setPending(DrmPlane::PropertyIndex::CrtcId, activePending() ? pending.crtc->id() : 0);
|
pending.crtc->primaryPlane()->setPending(DrmPlane::PropertyIndex::CrtcId, activePending() ? pending.crtc->id() : 0);
|
||||||
pending.crtc->primaryPlane()->setTransformation(pending.bufferTransformation);
|
pending.crtc->primaryPlane()->setTransformation(pending.bufferTransformation);
|
||||||
|
@ -400,7 +399,7 @@ void DrmPipeline::applyPendingChanges()
|
||||||
|
|
||||||
QSize DrmPipeline::bufferSize() const
|
QSize DrmPipeline::bufferSize() const
|
||||||
{
|
{
|
||||||
const auto modeSize = m_connector->modes().at(pending.modeIndex)->size();
|
const auto modeSize = pending.mode->size();
|
||||||
if (pending.bufferTransformation & (DrmPlane::Transformation::Rotate90 | DrmPlane::Transformation::Rotate270)) {
|
if (pending.bufferTransformation & (DrmPlane::Transformation::Rotate90 | DrmPlane::Transformation::Rotate270)) {
|
||||||
return modeSize.transposed();
|
return modeSize.transposed();
|
||||||
}
|
}
|
||||||
|
@ -409,7 +408,7 @@ QSize DrmPipeline::bufferSize() const
|
||||||
|
|
||||||
QSize DrmPipeline::sourceSize() const
|
QSize DrmPipeline::sourceSize() const
|
||||||
{
|
{
|
||||||
const auto modeSize = m_connector->modes().at(pending.modeIndex)->size();
|
const auto modeSize = pending.mode->size();
|
||||||
if (pending.sourceTransformation & (DrmPlane::Transformation::Rotate90 | DrmPlane::Transformation::Rotate270)) {
|
if (pending.sourceTransformation & (DrmPlane::Transformation::Rotate90 | DrmPlane::Transformation::Rotate270)) {
|
||||||
return modeSize.transposed();
|
return modeSize.transposed();
|
||||||
}
|
}
|
||||||
|
@ -418,7 +417,7 @@ QSize DrmPipeline::sourceSize() const
|
||||||
|
|
||||||
bool DrmPipeline::isCursorVisible() const
|
bool DrmPipeline::isCursorVisible() const
|
||||||
{
|
{
|
||||||
const QRect mode = QRect(QPoint(), m_connector->modes().at(pending.modeIndex)->size());
|
const QRect mode = QRect(QPoint(), pending.mode->size());
|
||||||
return pending.cursorBo && QRect(pending.cursorPos, pending.cursorBo->size()).intersects(mode);
|
return pending.cursorBo && QRect(pending.cursorPos, pending.cursorBo->size()).intersects(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -500,7 +499,7 @@ bool DrmPipeline::needsModeset() const
|
||||||
{
|
{
|
||||||
return pending.crtc != m_current.crtc
|
return pending.crtc != m_current.crtc
|
||||||
|| pending.active != m_current.active
|
|| pending.active != m_current.active
|
||||||
|| pending.modeIndex != m_current.modeIndex
|
|| pending.mode != m_current.mode
|
||||||
|| pending.rgbRange != m_current.rgbRange
|
|| pending.rgbRange != m_current.rgbRange
|
||||||
|| pending.bufferTransformation != m_current.bufferTransformation
|
|| pending.bufferTransformation != m_current.bufferTransformation
|
||||||
|| m_connector->linkStatus() == DrmConnector::LinkStatus::Bad
|
|| m_connector->linkStatus() == DrmConnector::LinkStatus::Bad
|
||||||
|
@ -509,7 +508,7 @@ bool DrmPipeline::needsModeset() const
|
||||||
|
|
||||||
bool DrmPipeline::activePending() const
|
bool DrmPipeline::activePending() const
|
||||||
{
|
{
|
||||||
return pending.crtc && pending.active;
|
return pending.crtc && pending.mode && pending.active;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrmPipeline::revertPendingChanges()
|
void DrmPipeline::revertPendingChanges()
|
||||||
|
|
|
@ -30,6 +30,7 @@ class DrmCrtc;
|
||||||
class DrmBuffer;
|
class DrmBuffer;
|
||||||
class DrmDumbBuffer;
|
class DrmDumbBuffer;
|
||||||
class GammaRamp;
|
class GammaRamp;
|
||||||
|
class DrmConnectorMode;
|
||||||
|
|
||||||
class DrmGammaRamp
|
class DrmGammaRamp
|
||||||
{
|
{
|
||||||
|
@ -97,7 +98,7 @@ public:
|
||||||
DrmCrtc *crtc = nullptr;
|
DrmCrtc *crtc = nullptr;
|
||||||
bool active = true; // whether or not the pipeline should be currently used
|
bool active = true; // whether or not the pipeline should be currently used
|
||||||
bool enabled = true;// whether or not the pipeline needs a crtc
|
bool enabled = true;// whether or not the pipeline needs a crtc
|
||||||
int modeIndex = 0;
|
QSharedPointer<DrmConnectorMode> mode;
|
||||||
uint32_t overscan = 0;
|
uint32_t overscan = 0;
|
||||||
AbstractWaylandOutput::RgbRange rgbRange = AbstractWaylandOutput::RgbRange::Automatic;
|
AbstractWaylandOutput::RgbRange rgbRange = AbstractWaylandOutput::RgbRange::Automatic;
|
||||||
RenderLoopPrivate::SyncMode syncMode = RenderLoopPrivate::SyncMode::Fixed;
|
RenderLoopPrivate::SyncMode syncMode = RenderLoopPrivate::SyncMode::Fixed;
|
||||||
|
|
|
@ -33,9 +33,8 @@ bool DrmPipeline::presentLegacy()
|
||||||
|
|
||||||
bool DrmPipeline::legacyModeset()
|
bool DrmPipeline::legacyModeset()
|
||||||
{
|
{
|
||||||
auto mode = m_connector->modes().at(pending.modeIndex);
|
|
||||||
uint32_t connId = m_connector->id();
|
uint32_t connId = m_connector->id();
|
||||||
if (!checkTestBuffer() || drmModeSetCrtc(gpu()->fd(), pending.crtc->id(), m_primaryBuffer->bufferId(), 0, 0, &connId, 1, mode->nativeMode()) != 0) {
|
if (!checkTestBuffer() || drmModeSetCrtc(gpu()->fd(), pending.crtc->id(), m_primaryBuffer->bufferId(), 0, 0, &connId, 1, pending.mode->nativeMode()) != 0) {
|
||||||
qCWarning(KWIN_DRM) << "Modeset failed!" << strerror(errno);
|
qCWarning(KWIN_DRM) << "Modeset failed!" << strerror(errno);
|
||||||
pending = m_next;
|
pending = m_next;
|
||||||
m_primaryBuffer = m_oldTestBuffer;
|
m_primaryBuffer = m_oldTestBuffer;
|
||||||
|
|
Loading…
Reference in a new issue