linuxfb: add experimental support for DRM dumb buffers
Add a QFbScreen implementation that uses DRM dumb buffers and page flipping, thus implementing a vsynced, double (triple) buffered plain software platform plugin. Besides better supporting systems that by now only do fbdev via (possibly buggy) emulation, this can also be an enabler for implementing certain types of 2D accelerated compositors e.g. for Wayland. Enable with QT_QPA_FB_DRM=1. Right now there is no good way to autodetect the support for dumb buffers early enough so the default is always the traditional fbdev path. Long-term this will also enable proper multi-display support like with eglfs' DRM backends. Multiple QScreens are not yet reported currently due to the single-screen limitations of fbconvenience. The generic DRM code is shared with eglfs, meaning configuration happens via the JSON file specified in QT_QPA_(EGLFS_)KMS_CONFIG. This allows changing the screen resolution, disabling outputs, etc. [ChangeLog][Platform Specific Changes][linuxfb] Added experimental support for DRM dumb buffers. Enable by setting the environment variable QT_QPA_FB_DRM to 1. Task-number: QTBUG-56306 Change-Id: I4bdcf16fff67412183220dffa0c4ea235c5cad3d Reviewed-by: Andy Nichols <andy.nichols@qt.io>
This commit is contained in:
parent
705e3f68df
commit
1f81ba45ee
@ -190,6 +190,11 @@ void QFbScreen::setGeometry(const QRect &rect)
|
|||||||
resizeMaximizedWindows();
|
resizeMaximizedWindows();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QFbScreen::initialize()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
QRegion QFbScreen::doRedraw()
|
QRegion QFbScreen::doRedraw()
|
||||||
{
|
{
|
||||||
const QPoint screenOffset = mGeometry.topLeft();
|
const QPoint screenOffset = mGeometry.topLeft();
|
||||||
|
@ -76,6 +76,8 @@ public:
|
|||||||
QFbScreen();
|
QFbScreen();
|
||||||
~QFbScreen();
|
~QFbScreen();
|
||||||
|
|
||||||
|
virtual bool initialize();
|
||||||
|
|
||||||
QRect geometry() const Q_DECL_OVERRIDE { return mGeometry; }
|
QRect geometry() const Q_DECL_OVERRIDE { return mGeometry; }
|
||||||
int depth() const Q_DECL_OVERRIDE { return mDepth; }
|
int depth() const Q_DECL_OVERRIDE { return mDepth; }
|
||||||
QImage::Format format() const Q_DECL_OVERRIDE { return mFormat; }
|
QImage::Format format() const Q_DECL_OVERRIDE { return mFormat; }
|
||||||
|
@ -10,8 +10,18 @@ QT += \
|
|||||||
qtHaveModule(input_support-private): \
|
qtHaveModule(input_support-private): \
|
||||||
QT += input_support-private
|
QT += input_support-private
|
||||||
|
|
||||||
SOURCES = main.cpp qlinuxfbintegration.cpp qlinuxfbscreen.cpp
|
SOURCES = main.cpp \
|
||||||
HEADERS = qlinuxfbintegration.h qlinuxfbscreen.h
|
qlinuxfbintegration.cpp \
|
||||||
|
qlinuxfbscreen.cpp
|
||||||
|
|
||||||
|
HEADERS = qlinuxfbintegration.h \
|
||||||
|
qlinuxfbscreen.h
|
||||||
|
|
||||||
|
qtHaveModule(kms_support-private) {
|
||||||
|
QT += kms_support-private
|
||||||
|
SOURCES += qlinuxfbdrmscreen.cpp
|
||||||
|
HEADERS += qlinuxfbdrmscreen.h
|
||||||
|
}
|
||||||
|
|
||||||
OTHER_FILES += linuxfb.json
|
OTHER_FILES += linuxfb.json
|
||||||
|
|
||||||
|
409
src/plugins/platforms/linuxfb/qlinuxfbdrmscreen.cpp
Normal file
409
src/plugins/platforms/linuxfb/qlinuxfbdrmscreen.cpp
Normal file
@ -0,0 +1,409 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 3 requirements
|
||||||
|
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 2.0 or (at your option) the GNU General
|
||||||
|
** Public license version 3 or any later version approved by the KDE Free
|
||||||
|
** Qt Foundation. The licenses are as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||||
|
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
// Experimental DRM dumb buffer backend.
|
||||||
|
//
|
||||||
|
// TODO:
|
||||||
|
// Multiscreen: QWindow-QScreen(-output) association. Needs some reorg (device cannot be owned by screen)
|
||||||
|
// Find card via devicediscovery like in eglfs_kms.
|
||||||
|
// Mode restore like QEglFSKmsInterruptHandler.
|
||||||
|
// Formats other then 32 bpp?
|
||||||
|
// grabWindow
|
||||||
|
|
||||||
|
#include "qlinuxfbdrmscreen.h"
|
||||||
|
#include <QLoggingCategory>
|
||||||
|
#include <QGuiApplication>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QtFbSupport/private/qfbcursor_p.h>
|
||||||
|
#include <QtFbSupport/private/qfbwindow_p.h>
|
||||||
|
#include <QtKmsSupport/private/qkmsdevice_p.h>
|
||||||
|
#include <QtCore/private/qcore_unix_p.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
Q_LOGGING_CATEGORY(qLcFbDrm, "qt.qpa.fb")
|
||||||
|
|
||||||
|
static const int BUFFER_COUNT = 2;
|
||||||
|
|
||||||
|
class QLinuxFbDevice : public QKmsDevice
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct Framebuffer {
|
||||||
|
Framebuffer() : handle(0), pitch(0), size(0), fb(0), p(MAP_FAILED) { }
|
||||||
|
uint32_t handle;
|
||||||
|
uint32_t pitch;
|
||||||
|
uint64_t size;
|
||||||
|
uint32_t fb;
|
||||||
|
void *p;
|
||||||
|
QImage wrapper;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Output {
|
||||||
|
Output() : backFb(0), flipped(false) { }
|
||||||
|
QKmsOutput kmsOutput;
|
||||||
|
Framebuffer fb[BUFFER_COUNT];
|
||||||
|
QRegion dirty[BUFFER_COUNT];
|
||||||
|
int backFb;
|
||||||
|
bool flipped;
|
||||||
|
QSize currentRes() const {
|
||||||
|
const drmModeModeInfo &modeInfo(kmsOutput.modes[kmsOutput.mode]);
|
||||||
|
return QSize(modeInfo.hdisplay, modeInfo.vdisplay);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
QLinuxFbDevice(QKmsScreenConfig *screenConfig);
|
||||||
|
|
||||||
|
bool open() override;
|
||||||
|
void close() override;
|
||||||
|
|
||||||
|
void createFramebuffers();
|
||||||
|
void destroyFramebuffers();
|
||||||
|
void setMode();
|
||||||
|
|
||||||
|
void swapBuffers(Output *output);
|
||||||
|
|
||||||
|
int outputCount() const { return m_outputs.count(); }
|
||||||
|
Output *output(int idx) { return &m_outputs[idx]; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void *nativeDisplay() const override;
|
||||||
|
QPlatformScreen *createScreen(const QKmsOutput &output) override;
|
||||||
|
void registerScreen(QPlatformScreen *screen,
|
||||||
|
const QPoint &virtualPos,
|
||||||
|
const QList<QPlatformScreen *> &virtualSiblings) override;
|
||||||
|
|
||||||
|
bool createFramebuffer(Output *output, int bufferIdx);
|
||||||
|
void destroyFramebuffer(Output *output, int bufferIdx);
|
||||||
|
|
||||||
|
static void pageFlipHandler(int fd, unsigned int sequence,
|
||||||
|
unsigned int tv_sec, unsigned int tv_usec, void *user_data);
|
||||||
|
|
||||||
|
QVector<Output> m_outputs;
|
||||||
|
};
|
||||||
|
|
||||||
|
QLinuxFbDevice::QLinuxFbDevice(QKmsScreenConfig *screenConfig)
|
||||||
|
: QKmsDevice(screenConfig, QStringLiteral("/dev/dri/card0"))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QLinuxFbDevice::open()
|
||||||
|
{
|
||||||
|
int fd = qt_safe_open(devicePath().toLocal8Bit().constData(), O_RDWR | O_CLOEXEC);
|
||||||
|
if (fd == -1) {
|
||||||
|
qErrnoWarning("Could not open DRM device %s", qPrintable(devicePath()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t hasDumbBuf = 0;
|
||||||
|
if (drmGetCap(fd, DRM_CAP_DUMB_BUFFER, &hasDumbBuf) == -1 || !hasDumbBuf) {
|
||||||
|
qWarning("Dumb buffers not supported");
|
||||||
|
qt_safe_close(fd);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
setFd(fd);
|
||||||
|
|
||||||
|
qCDebug(qLcFbDrm, "DRM device %s opened", qPrintable(devicePath()));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QLinuxFbDevice::close()
|
||||||
|
{
|
||||||
|
for (Output &output : m_outputs)
|
||||||
|
output.kmsOutput.cleanup(this); // restore mode
|
||||||
|
|
||||||
|
m_outputs.clear();
|
||||||
|
|
||||||
|
if (fd() != -1) {
|
||||||
|
qCDebug(qLcFbDrm, "Closing DRM device");
|
||||||
|
qt_safe_close(fd());
|
||||||
|
setFd(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void *QLinuxFbDevice::nativeDisplay() const
|
||||||
|
{
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPlatformScreen *QLinuxFbDevice::createScreen(const QKmsOutput &output)
|
||||||
|
{
|
||||||
|
qCDebug(qLcFbDrm, "Got a new output: %s", qPrintable(output.name));
|
||||||
|
Output o;
|
||||||
|
o.kmsOutput = output;
|
||||||
|
m_outputs.append(o);
|
||||||
|
return nullptr; // no platformscreen, we are not a platform plugin
|
||||||
|
}
|
||||||
|
|
||||||
|
void QLinuxFbDevice::registerScreen(QPlatformScreen *screen,
|
||||||
|
const QPoint &virtualPos,
|
||||||
|
const QList<QPlatformScreen *> &virtualSiblings)
|
||||||
|
{
|
||||||
|
Q_UNUSED(screen);
|
||||||
|
Q_UNUSED(virtualPos);
|
||||||
|
Q_UNUSED(virtualSiblings);
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QLinuxFbDevice::createFramebuffer(QLinuxFbDevice::Output *output, int bufferIdx)
|
||||||
|
{
|
||||||
|
const QSize size = output->currentRes();
|
||||||
|
const uint32_t w = size.width();
|
||||||
|
const uint32_t h = size.height();
|
||||||
|
drm_mode_create_dumb creq = {
|
||||||
|
h,
|
||||||
|
w,
|
||||||
|
32,
|
||||||
|
0, 0, 0, 0
|
||||||
|
};
|
||||||
|
if (drmIoctl(fd(), DRM_IOCTL_MODE_CREATE_DUMB, &creq) == -1) {
|
||||||
|
qErrnoWarning(errno, "Failed to create dumb buffer");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Framebuffer &fb(output->fb[bufferIdx]);
|
||||||
|
fb.handle = creq.handle;
|
||||||
|
fb.pitch = creq.pitch;
|
||||||
|
fb.size = creq.size;
|
||||||
|
qCDebug(qLcFbDrm, "Got a dumb buffer for size %dx%d, handle %u, pitch %u, size %u",
|
||||||
|
w, h, fb.handle, fb.pitch, (uint) fb.size);
|
||||||
|
|
||||||
|
if (drmModeAddFB(fd(), w, h, 24, 32, fb.pitch, fb.handle, &fb.fb) == -1) {
|
||||||
|
qErrnoWarning(errno, "Failed to add FB");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
drm_mode_map_dumb mreq = {
|
||||||
|
fb.handle,
|
||||||
|
0, 0
|
||||||
|
};
|
||||||
|
if (drmIoctl(fd(), DRM_IOCTL_MODE_MAP_DUMB, &mreq) == -1) {
|
||||||
|
qErrnoWarning(errno, "Failed to map dumb buffer");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
fb.p = mmap(0, fb.size, PROT_READ | PROT_WRITE, MAP_SHARED, fd(), mreq.offset);
|
||||||
|
if (fb.p == MAP_FAILED) {
|
||||||
|
qErrnoWarning(errno, "Failed to mmap dumb buffer");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
qCDebug(qLcFbDrm, "FB is %u, mapped at %p", fb.fb, fb.p);
|
||||||
|
memset(fb.p, 0, fb.size);
|
||||||
|
|
||||||
|
fb.wrapper = QImage(static_cast<uchar *>(fb.p), w, h, fb.pitch, QImage::Format_ARGB32);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QLinuxFbDevice::createFramebuffers()
|
||||||
|
{
|
||||||
|
for (Output &output : m_outputs) {
|
||||||
|
for (int i = 0; i < BUFFER_COUNT; ++i) {
|
||||||
|
if (!createFramebuffer(&output, i))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
output.backFb = 0;
|
||||||
|
output.flipped = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QLinuxFbDevice::destroyFramebuffer(QLinuxFbDevice::Output *output, int bufferIdx)
|
||||||
|
{
|
||||||
|
Framebuffer &fb(output->fb[bufferIdx]);
|
||||||
|
if (fb.p != MAP_FAILED)
|
||||||
|
munmap(fb.p, fb.size);
|
||||||
|
if (fb.fb) {
|
||||||
|
if (drmModeRmFB(fd(), fb.fb) == -1)
|
||||||
|
qErrnoWarning("Failed to remove fb");
|
||||||
|
}
|
||||||
|
if (fb.handle) {
|
||||||
|
drm_mode_destroy_dumb dreq = { fb.handle };
|
||||||
|
if (drmIoctl(fd(), DRM_IOCTL_MODE_DESTROY_DUMB, &dreq) == -1)
|
||||||
|
qErrnoWarning(errno, "Failed to destroy dumb buffer %u", fb.handle);
|
||||||
|
}
|
||||||
|
fb = Framebuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QLinuxFbDevice::destroyFramebuffers()
|
||||||
|
{
|
||||||
|
for (Output &output : m_outputs) {
|
||||||
|
for (int i = 0; i < BUFFER_COUNT; ++i)
|
||||||
|
destroyFramebuffer(&output, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QLinuxFbDevice::setMode()
|
||||||
|
{
|
||||||
|
for (Output &output : m_outputs) {
|
||||||
|
drmModeModeInfo &modeInfo(output.kmsOutput.modes[output.kmsOutput.mode]);
|
||||||
|
if (drmModeSetCrtc(fd(), output.kmsOutput.crtc_id, output.fb[0].fb, 0, 0,
|
||||||
|
&output.kmsOutput.connector_id, 1, &modeInfo) == -1) {
|
||||||
|
qErrnoWarning(errno, "Failed to set mode");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
output.kmsOutput.mode_set = true; // have cleanup() to restore the mode
|
||||||
|
output.kmsOutput.setPowerState(this, QPlatformScreen::PowerStateOn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QLinuxFbDevice::pageFlipHandler(int fd, unsigned int sequence,
|
||||||
|
unsigned int tv_sec, unsigned int tv_usec,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
Q_UNUSED(fd);
|
||||||
|
Q_UNUSED(sequence);
|
||||||
|
Q_UNUSED(tv_sec);
|
||||||
|
Q_UNUSED(tv_usec);
|
||||||
|
|
||||||
|
Output *output = static_cast<Output *>(user_data);
|
||||||
|
output->backFb = (output->backFb + 1) % BUFFER_COUNT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QLinuxFbDevice::swapBuffers(Output *output)
|
||||||
|
{
|
||||||
|
Framebuffer &fb(output->fb[output->backFb]);
|
||||||
|
if (drmModePageFlip(fd(), output->kmsOutput.crtc_id, fb.fb, DRM_MODE_PAGE_FLIP_EVENT, output) == -1) {
|
||||||
|
qErrnoWarning(errno, "Page flip failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int fbIdx = output->backFb;
|
||||||
|
while (output->backFb == fbIdx) {
|
||||||
|
drmEventContext drmEvent = {
|
||||||
|
DRM_EVENT_CONTEXT_VERSION,
|
||||||
|
nullptr,
|
||||||
|
pageFlipHandler
|
||||||
|
};
|
||||||
|
// Blocks until there is something to read on the drm fd
|
||||||
|
// and calls back pageFlipHandler once the flip completes.
|
||||||
|
drmHandleEvent(fd(), &drmEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QLinuxFbDrmScreen::QLinuxFbDrmScreen(const QStringList &args)
|
||||||
|
: m_screenConfig(nullptr),
|
||||||
|
m_device(nullptr)
|
||||||
|
{
|
||||||
|
Q_UNUSED(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
QLinuxFbDrmScreen::~QLinuxFbDrmScreen()
|
||||||
|
{
|
||||||
|
if (m_device) {
|
||||||
|
m_device->destroyFramebuffers();
|
||||||
|
m_device->close();
|
||||||
|
delete m_device;
|
||||||
|
}
|
||||||
|
delete m_screenConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QLinuxFbDrmScreen::initialize()
|
||||||
|
{
|
||||||
|
m_screenConfig = new QKmsScreenConfig;
|
||||||
|
m_device = new QLinuxFbDevice(m_screenConfig);
|
||||||
|
if (!m_device->open())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Discover outputs. Calls back Device::createScreen().
|
||||||
|
m_device->createScreens();
|
||||||
|
// Now off to dumb buffer specifics.
|
||||||
|
m_device->createFramebuffers();
|
||||||
|
// Do the modesetting.
|
||||||
|
m_device->setMode();
|
||||||
|
|
||||||
|
QLinuxFbDevice::Output *output(m_device->output(0));
|
||||||
|
|
||||||
|
mGeometry = QRect(QPoint(0, 0), output->currentRes());
|
||||||
|
mDepth = 32;
|
||||||
|
mFormat = QImage::Format_ARGB32;
|
||||||
|
mPhysicalSize = output->kmsOutput.physical_size;
|
||||||
|
qCDebug(qLcFbDrm) << mGeometry << mPhysicalSize;
|
||||||
|
|
||||||
|
QFbScreen::initializeCompositor();
|
||||||
|
|
||||||
|
mCursor = new QFbCursor(this);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRegion QLinuxFbDrmScreen::doRedraw()
|
||||||
|
{
|
||||||
|
const QRegion dirty = QFbScreen::doRedraw();
|
||||||
|
if (dirty.isEmpty())
|
||||||
|
return dirty;
|
||||||
|
|
||||||
|
QLinuxFbDevice::Output *output(m_device->output(0));
|
||||||
|
|
||||||
|
for (int i = 0; i < BUFFER_COUNT; ++i)
|
||||||
|
output->dirty[i] += dirty;
|
||||||
|
|
||||||
|
if (output->fb[output->backFb].wrapper.isNull())
|
||||||
|
return dirty;
|
||||||
|
|
||||||
|
QPainter pntr(&output->fb[output->backFb].wrapper);
|
||||||
|
// Image has alpha but no need for blending at this stage.
|
||||||
|
// Do not waste time with the default SourceOver.
|
||||||
|
pntr.setCompositionMode(QPainter::CompositionMode_Source);
|
||||||
|
for (const QRect &rect : qAsConst(output->dirty[output->backFb]))
|
||||||
|
pntr.drawImage(rect, mScreenImage, rect);
|
||||||
|
pntr.end();
|
||||||
|
|
||||||
|
output->dirty[output->backFb] = QRegion();
|
||||||
|
|
||||||
|
m_device->swapBuffers(output);
|
||||||
|
|
||||||
|
return dirty;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPixmap QLinuxFbDrmScreen::grabWindow(WId wid, int x, int y, int width, int height) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(wid);
|
||||||
|
Q_UNUSED(x);
|
||||||
|
Q_UNUSED(y);
|
||||||
|
Q_UNUSED(width);
|
||||||
|
Q_UNUSED(height);
|
||||||
|
|
||||||
|
return QPixmap();
|
||||||
|
}
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
68
src/plugins/platforms/linuxfb/qlinuxfbdrmscreen.h
Normal file
68
src/plugins/platforms/linuxfb/qlinuxfbdrmscreen.h
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 3 requirements
|
||||||
|
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 2.0 or (at your option) the GNU General
|
||||||
|
** Public license version 3 or any later version approved by the KDE Free
|
||||||
|
** Qt Foundation. The licenses are as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||||
|
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QLINUXFBDRMSCREEN_H
|
||||||
|
#define QLINUXFBDRMSCREEN_H
|
||||||
|
|
||||||
|
#include <QtFbSupport/private/qfbscreen_p.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class QKmsScreenConfig;
|
||||||
|
class QLinuxFbDevice;
|
||||||
|
|
||||||
|
class QLinuxFbDrmScreen : public QFbScreen
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
QLinuxFbDrmScreen(const QStringList &args);
|
||||||
|
~QLinuxFbDrmScreen();
|
||||||
|
|
||||||
|
bool initialize() override;
|
||||||
|
QRegion doRedraw() override;
|
||||||
|
QPixmap grabWindow(WId wid, int x, int y, int width, int height) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QKmsScreenConfig *m_screenConfig;
|
||||||
|
QLinuxFbDevice *m_device;
|
||||||
|
};
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // QLINUXFBDRMSCREEN_H
|
@ -39,6 +39,9 @@
|
|||||||
|
|
||||||
#include "qlinuxfbintegration.h"
|
#include "qlinuxfbintegration.h"
|
||||||
#include "qlinuxfbscreen.h"
|
#include "qlinuxfbscreen.h"
|
||||||
|
#if QT_CONFIG(kms)
|
||||||
|
#include "qlinuxfbdrmscreen.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <QtFontDatabaseSupport/private/qgenericunixfontdatabase_p.h>
|
#include <QtFontDatabaseSupport/private/qgenericunixfontdatabase_p.h>
|
||||||
#include <QtServiceSupport/private/qgenericunixservices_p.h>
|
#include <QtServiceSupport/private/qgenericunixservices_p.h>
|
||||||
@ -69,9 +72,15 @@
|
|||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
QLinuxFbIntegration::QLinuxFbIntegration(const QStringList ¶mList)
|
QLinuxFbIntegration::QLinuxFbIntegration(const QStringList ¶mList)
|
||||||
: m_fontDb(new QGenericUnixFontDatabase),
|
: m_primaryScreen(nullptr),
|
||||||
|
m_fontDb(new QGenericUnixFontDatabase),
|
||||||
m_services(new QGenericUnixServices)
|
m_services(new QGenericUnixServices)
|
||||||
{
|
{
|
||||||
|
#if QT_CONFIG(kms)
|
||||||
|
if (qEnvironmentVariableIntValue("QT_QPA_FB_DRM") != 0)
|
||||||
|
m_primaryScreen = new QLinuxFbDrmScreen(paramList);
|
||||||
|
#endif
|
||||||
|
if (!m_primaryScreen)
|
||||||
m_primaryScreen = new QLinuxFbScreen(paramList);
|
m_primaryScreen = new QLinuxFbScreen(paramList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class QAbstractEventDispatcher;
|
class QAbstractEventDispatcher;
|
||||||
class QLinuxFbScreen;
|
class QFbScreen;
|
||||||
class QFbVtHandler;
|
class QFbVtHandler;
|
||||||
|
|
||||||
class QLinuxFbIntegration : public QPlatformIntegration, public QPlatformNativeInterface
|
class QLinuxFbIntegration : public QPlatformIntegration, public QPlatformNativeInterface
|
||||||
@ -74,7 +74,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
void createInputHandlers();
|
void createInputHandlers();
|
||||||
|
|
||||||
QLinuxFbScreen *m_primaryScreen;
|
QFbScreen *m_primaryScreen;
|
||||||
QPlatformInputContext *m_inputContext;
|
QPlatformInputContext *m_inputContext;
|
||||||
QScopedPointer<QPlatformFontDatabase> m_fontDb;
|
QScopedPointer<QPlatformFontDatabase> m_fontDb;
|
||||||
QScopedPointer<QPlatformServices> m_services;
|
QScopedPointer<QPlatformServices> m_services;
|
||||||
|
@ -54,11 +54,11 @@ public:
|
|||||||
QLinuxFbScreen(const QStringList &args);
|
QLinuxFbScreen(const QStringList &args);
|
||||||
~QLinuxFbScreen();
|
~QLinuxFbScreen();
|
||||||
|
|
||||||
bool initialize();
|
bool initialize() override;
|
||||||
|
|
||||||
QPixmap grabWindow(WId wid, int x, int y, int width, int height) const Q_DECL_OVERRIDE;
|
QPixmap grabWindow(WId wid, int x, int y, int width, int height) const override;
|
||||||
|
|
||||||
QRegion doRedraw() Q_DECL_OVERRIDE;
|
QRegion doRedraw() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QStringList mArgs;
|
QStringList mArgs;
|
||||||
|
Loading…
Reference in New Issue
Block a user