diff --git a/plugins/platforms/fbdev/fb_backend.h b/plugins/platforms/fbdev/fb_backend.h --- a/plugins/platforms/fbdev/fb_backend.h +++ b/plugins/platforms/fbdev/fb_backend.h @@ -2,7 +2,8 @@ KWin - the KDE window manager This file is part of the KDE project. -Copyright (C) 2015 Martin Gräßlin +Copyright 2015 Martin Gräßlin +Copyright 2019 Roman Gilg This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -19,14 +20,38 @@ *********************************************************************/ #ifndef KWIN_FB_BACKEND_H #define KWIN_FB_BACKEND_H +#include "abstract_output.h" #include "platform.h" #include #include namespace KWin { +class FramebufferOutput : public AbstractOutput +{ + Q_OBJECT + +public: + FramebufferOutput(QObject *parent = nullptr) : AbstractOutput(parent) {} + virtual ~FramebufferOutput() = default; + + QSize pixelSize() const override { + return m_pixelSize; + } + void setPixelSize(const QSize &set) { + m_pixelSize = set; + } + + void setRawPhysicalSize(const QSize &set) { + AbstractOutput::setRawPhysicalSize(set); + } + +private: + QSize m_pixelSize; +}; + class KWIN_EXPORT FramebufferBackend : public Platform { Q_OBJECT @@ -39,23 +64,14 @@ Screens *createScreens(QObject *parent = nullptr) override; QPainterBackend *createQPainterBackend() override; - QSize screenSize() const override { - return m_resolution; - } + QSize screenSize() const override; void init() override; bool isValid() const { return m_fd >= 0; } - QSize size() const { - return m_resolution; - } - QSize physicalSize() const { - return m_physicalSize; - } - void map(); void unmap(); void *mappedMemory() const { @@ -78,16 +94,20 @@ return m_bgr; } + Outputs outputs() const override; + Outputs enabledOutputs() const override; + QVector supportedCompositors() const override { return QVector{QPainterCompositing}; } private: void openFrameBuffer(); bool handleScreenInfo(); void initImageFormat(); - QSize m_resolution; - QSize m_physicalSize; + + QVector m_outputs; + QByteArray m_id; struct Color { quint32 offset; diff --git a/plugins/platforms/fbdev/fb_backend.cpp b/plugins/platforms/fbdev/fb_backend.cpp --- a/plugins/platforms/fbdev/fb_backend.cpp +++ b/plugins/platforms/fbdev/fb_backend.cpp @@ -18,11 +18,12 @@ along with this program. If not, see . *********************************************************************/ #include "fb_backend.h" + #include "composite.h" #include "logging.h" #include "logind.h" #include "scene_qpainter_fb_backend.h" -#include "screens.h" +#include "outputscreens.h" #include "virtual_terminal.h" #include "udev.h" // system @@ -51,7 +52,7 @@ Screens *FramebufferBackend::createScreens(QObject *parent) { - return new BasicScreens(this, parent); + return new OutputScreens(this, parent); } QPainterBackend *FramebufferBackend::createQPainterBackend() @@ -135,8 +136,11 @@ return false; } - m_resolution = QSize(varinfo.xres, varinfo.yres); - m_physicalSize = QSize(varinfo.width, varinfo.height); + auto *output = new FramebufferOutput(this); + output->setPixelSize(QSize(varinfo.xres, varinfo.yres)); + output->setRawPhysicalSize(QSize(varinfo.width, varinfo.height)); + m_outputs << output; + m_id = QByteArray(fixinfo.id); m_red = {varinfo.red.offset, varinfo.red.length}; m_green = {varinfo.green.offset, varinfo.green.length}; @@ -178,6 +182,14 @@ m_memory = nullptr; } +QSize FramebufferBackend::screenSize() const +{ + if (m_outputs.isEmpty()) { + return QSize(); + } + return m_outputs[0]->pixelSize(); +} + QImage::Format FramebufferBackend::imageFormat() const { return m_imageFormat; @@ -245,4 +257,14 @@ } } +Outputs FramebufferBackend::outputs() const +{ + return m_outputs; +} + +Outputs FramebufferBackend::enabledOutputs() const +{ + return m_outputs; +} + } diff --git a/plugins/platforms/fbdev/scene_qpainter_fb_backend.h b/plugins/platforms/fbdev/scene_qpainter_fb_backend.h --- a/plugins/platforms/fbdev/scene_qpainter_fb_backend.h +++ b/plugins/platforms/fbdev/scene_qpainter_fb_backend.h @@ -36,15 +36,25 @@ virtual ~FramebufferQPainterBackend(); QImage *buffer() override; + QImage *bufferForScreen(int screenId) override; bool needsFullRepaint() const override; bool usesOverlayWindow() const override; void prepareRenderingFrame() override; void present(int mask, const QRegion &damage) override; + bool perScreenRendering() const override; private: + /** + * @brief mapped memory buffer on fb device + */ QImage m_renderBuffer; + /** + * @brief buffer to draw into + */ QImage m_backBuffer; + FramebufferBackend *m_backend; + bool m_needsFullRepaint; }; } diff --git a/plugins/platforms/fbdev/scene_qpainter_fb_backend.cpp b/plugins/platforms/fbdev/scene_qpainter_fb_backend.cpp --- a/plugins/platforms/fbdev/scene_qpainter_fb_backend.cpp +++ b/plugins/platforms/fbdev/scene_qpainter_fb_backend.cpp @@ -31,19 +31,19 @@ FramebufferQPainterBackend::FramebufferQPainterBackend(FramebufferBackend *backend) : QObject() , QPainterBackend() - , m_renderBuffer(backend->size(), QImage::Format_RGB32) + , m_renderBuffer(backend->screenSize(), QImage::Format_RGB32) , m_backend(backend) + , m_needsFullRepaint(true) { m_renderBuffer.fill(Qt::black); - m_backend->map(); - m_backBuffer = QImage((uchar*)backend->mappedMemory(), - backend->bytesPerLine() / (backend->bitsPerPixel() / 8), - backend->bufferSize() / backend->bytesPerLine(), - backend->bytesPerLine(), backend->imageFormat()); - + m_backBuffer = QImage((uchar*)m_backend->mappedMemory(), + m_backend->bytesPerLine() / (m_backend->bitsPerPixel() / 8), + m_backend->bufferSize() / m_backend->bytesPerLine(), + m_backend->bytesPerLine(), m_backend->imageFormat()); m_backBuffer.fill(Qt::black); + connect(VirtualTerminal::self(), &VirtualTerminal::activeChanged, this, [this] (bool active) { if (active) { @@ -58,27 +58,37 @@ FramebufferQPainterBackend::~FramebufferQPainterBackend() = default; -QImage *FramebufferQPainterBackend::buffer() +QImage* FramebufferQPainterBackend::buffer() +{ + return bufferForScreen(0); +} + +QImage* FramebufferQPainterBackend::bufferForScreen(int screenId) { + Q_UNUSED(screenId) return &m_renderBuffer; } bool FramebufferQPainterBackend::needsFullRepaint() const { - return false; + return m_needsFullRepaint; } void FramebufferQPainterBackend::prepareRenderingFrame() { + m_needsFullRepaint = true; } void FramebufferQPainterBackend::present(int mask, const QRegion &damage) { Q_UNUSED(mask) Q_UNUSED(damage) + if (!LogindIntegration::self()->isActiveSession()) { return; } + m_needsFullRepaint = false; + QPainter p(&m_backBuffer); p.drawImage(QPoint(0, 0), m_backend->isBGR() ? m_renderBuffer.rgbSwapped() : m_renderBuffer); } @@ -88,4 +98,9 @@ return false; } +bool FramebufferQPainterBackend::perScreenRendering() const +{ + return true; +} + }