Commit 4b3b5fa3 authored by Aleix Pol Gonzalez's avatar Aleix Pol Gonzalez 🐧 Committed by Aleix Pol Gonzalez
Browse files

fb: make it easier to run on nomodeset

In the few cases where the framebuffer is needed, we'd get problems
because ioctl(KWIN_FB_NO_VSYNC) fails.
This removes the code entirely to just use a timer to refresh.

BUG: 436053
parent 92fb680b
set(FBDEV_SOURCES
fb_backend.cpp
fbvsyncmonitor.cpp
logging.cpp
scene_qpainter_fb_backend.cpp
)
......
......@@ -7,7 +7,6 @@
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "fb_backend.h"
#include "fbvsyncmonitor.h"
#include "composite.h"
#include "logging.h"
......@@ -28,16 +27,12 @@
namespace KWin
{
FramebufferOutput::FramebufferOutput(FramebufferBackend *backend, QObject *parent)
FramebufferOutput::FramebufferOutput(QObject *parent)
: AbstractWaylandOutput(parent)
, m_renderLoop(new RenderLoop(this))
{
setName("FB-0");
if (!qEnvironmentVariableIsSet("KWIN_FB_NO_HW_VSYNC")) {
m_vsyncMonitor = FramebufferVsyncMonitor::create(backend->fileDescriptor(), this);
}
if (!m_vsyncMonitor) {
SoftwareVsyncMonitor *monitor = SoftwareVsyncMonitor::create(this);
monitor->setRefreshRate(m_renderLoop->refreshRate());
......@@ -160,7 +155,7 @@ bool FramebufferBackend::handleScreenInfo()
return false;
}
auto *output = new FramebufferOutput(this);
auto *output = new FramebufferOutput;
output->init(QSize(varinfo.xres, varinfo.yres), QSize(varinfo.width, varinfo.height));
m_outputs << output;
emit outputAdded(output);
......
......@@ -26,7 +26,7 @@ class FramebufferOutput : public AbstractWaylandOutput
Q_OBJECT
public:
explicit FramebufferOutput(FramebufferBackend *backend, QObject *parent = nullptr);
explicit FramebufferOutput(QObject *parent = nullptr);
~FramebufferOutput() override = default;
RenderLoop *renderLoop() const override;
......
/*
SPDX-FileCopyrightText: 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "fbvsyncmonitor.h"
#include <QThread>
#include <linux/fb.h>
#include <sys/ioctl.h>
#include <unistd.h>
namespace KWin
{
FramebufferVsyncMonitorHelper::FramebufferVsyncMonitorHelper(int fileDescriptor, QObject *parent)
: QObject(parent)
, m_fileDescriptor(fileDescriptor)
{
}
FramebufferVsyncMonitorHelper::~FramebufferVsyncMonitorHelper()
{
close(m_fileDescriptor);
}
void FramebufferVsyncMonitorHelper::poll()
{
if (ioctl(m_fileDescriptor, FBIO_WAITFORVSYNC)) {
emit errorOccurred();
} else {
emit vblankOccurred(std::chrono::steady_clock::now().time_since_epoch());
}
}
FramebufferVsyncMonitor::FramebufferVsyncMonitor(int fileDescriptor, QObject *parent)
: VsyncMonitor(parent)
, m_thread(new QThread)
, m_helper(new FramebufferVsyncMonitorHelper(fileDescriptor))
{
m_helper->moveToThread(m_thread);
connect(m_helper, &FramebufferVsyncMonitorHelper::errorOccurred,
this, &FramebufferVsyncMonitor::errorOccurred);
connect(m_helper, &FramebufferVsyncMonitorHelper::vblankOccurred,
this, &FramebufferVsyncMonitor::vblankOccurred);
m_thread->setObjectName(QStringLiteral("vsync event monitor"));
m_thread->start();
}
FramebufferVsyncMonitor::~FramebufferVsyncMonitor()
{
m_thread->quit();
m_thread->wait();
delete m_helper;
delete m_thread;
}
void FramebufferVsyncMonitor::arm()
{
QMetaObject::invokeMethod(m_helper, &FramebufferVsyncMonitorHelper::poll);
}
FramebufferVsyncMonitor *FramebufferVsyncMonitor::create(int fileDescriptor, QObject *parent)
{
const int threadFileDescriptor = dup(fileDescriptor);
if (threadFileDescriptor == -1) {
return nullptr;
}
return new FramebufferVsyncMonitor(threadFileDescriptor, parent);
}
} // namespace KWin
/*
SPDX-FileCopyrightText: 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include "vsyncmonitor.h"
namespace KWin
{
/**
* The FramebufferVsyncMonitorHelper class is responsible for waiting vsync events using the
* FBIO_WAITFORVSYNC ioctl. Note that the helper runs on a separate thread.
*/
class FramebufferVsyncMonitorHelper : public QObject
{
Q_OBJECT
public:
explicit FramebufferVsyncMonitorHelper(int fileDescriptor, QObject *parent = nullptr);
~FramebufferVsyncMonitorHelper() override;
public Q_SLOTS:
void poll();
Q_SIGNALS:
void errorOccurred();
void vblankOccurred(std::chrono::nanoseconds timestamp);
private:
int m_fileDescriptor;
};
/**
* The FramebufferVsyncMonitor class monitors vblank events using the FBIO_WAITFORVSYNC ioctl.
*/
class FramebufferVsyncMonitor : public VsyncMonitor
{
Q_OBJECT
public:
/**
* Creates a fbdev vsync monitor for the device with the specified file descriptor @p fd.
* This function returns @c null if an error has occurred.
*/
static FramebufferVsyncMonitor *create(int fd, QObject *parent);
~FramebufferVsyncMonitor() override;
public Q_SLOTS:
void arm() override;
private:
explicit FramebufferVsyncMonitor(int fileDescriptor, QObject *parent = nullptr);
QThread *m_thread;
FramebufferVsyncMonitorHelper *m_helper;
};
} // namespace KWin
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment