File indexing completed on 2026-06-07 16:15:42

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2019 Roman Gilg <subdiff@gmail.com>
0006     SPDX-FileCopyrightText: 2013, 2015 Martin Gräßlin <mgraesslin@kde.org>
0007 
0008     SPDX-License-Identifier: GPL-2.0-or-later
0009 */
0010 #pragma once
0011 
0012 #include "core/outputlayer.h"
0013 #include "qpainterbackend.h"
0014 #include "utils/damagejournal.h"
0015 
0016 #include <KWayland/Client/buffer.h>
0017 
0018 #include <QImage>
0019 #include <QObject>
0020 #include <QWeakPointer>
0021 
0022 namespace KWayland
0023 {
0024 namespace Client
0025 {
0026 class ShmPool;
0027 class Buffer;
0028 }
0029 }
0030 
0031 namespace KWin
0032 {
0033 class Output;
0034 namespace Wayland
0035 {
0036 class WaylandBackend;
0037 class WaylandOutput;
0038 class WaylandQPainterBackend;
0039 
0040 class WaylandQPainterBufferSlot
0041 {
0042 public:
0043     WaylandQPainterBufferSlot(QSharedPointer<KWayland::Client::Buffer> buffer);
0044     ~WaylandQPainterBufferSlot();
0045 
0046     QSharedPointer<KWayland::Client::Buffer> buffer;
0047     QImage image;
0048     int age = 0;
0049 };
0050 
0051 class WaylandQPainterPrimaryLayer : public OutputLayer
0052 {
0053 public:
0054     WaylandQPainterPrimaryLayer(WaylandOutput *output);
0055     ~WaylandQPainterPrimaryLayer() override;
0056 
0057     std::optional<OutputLayerBeginFrameInfo> beginFrame() override;
0058     bool endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override;
0059 
0060     void remapBuffer();
0061 
0062     WaylandQPainterBufferSlot *back() const;
0063 
0064     WaylandQPainterBufferSlot *acquire();
0065     void present();
0066 
0067     QRegion accumulateDamage(int bufferAge) const;
0068 
0069 private:
0070     WaylandOutput *m_waylandOutput;
0071     KWayland::Client::ShmPool *m_pool;
0072     DamageJournal m_damageJournal;
0073 
0074     std::vector<std::unique_ptr<WaylandQPainterBufferSlot>> m_slots;
0075     WaylandQPainterBufferSlot *m_back = nullptr;
0076     QSize m_swapchainSize;
0077 
0078     friend class WaylandQPainterBackend;
0079 };
0080 
0081 class WaylandQPainterCursorLayer : public OutputLayer
0082 {
0083     Q_OBJECT
0084 
0085 public:
0086     explicit WaylandQPainterCursorLayer(WaylandOutput *output);
0087     ~WaylandQPainterCursorLayer() override;
0088 
0089     qreal scale() const;
0090     void setScale(qreal scale);
0091 
0092     QPoint hotspot() const;
0093     void setHotspot(const QPoint &hotspot);
0094 
0095     QSize size() const;
0096     void setSize(const QSize &size);
0097 
0098     std::optional<OutputLayerBeginFrameInfo> beginFrame() override;
0099     bool endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override;
0100 
0101 private:
0102     WaylandOutput *m_output;
0103     QImage m_backingStore;
0104     QPoint m_hotspot;
0105     QSize m_size;
0106     qreal m_scale = 1.0;
0107 };
0108 
0109 class WaylandQPainterBackend : public QPainterBackend
0110 {
0111     Q_OBJECT
0112 public:
0113     explicit WaylandQPainterBackend(WaylandBackend *b);
0114     ~WaylandQPainterBackend() override;
0115 
0116     void present(Output *output) override;
0117     OutputLayer *primaryLayer(Output *output) override;
0118     WaylandQPainterCursorLayer *cursorLayer(Output *output);
0119 
0120 private:
0121     void createOutput(Output *waylandOutput);
0122 
0123     struct Layers
0124     {
0125         std::unique_ptr<WaylandQPainterPrimaryLayer> primaryLayer;
0126         std::unique_ptr<WaylandQPainterCursorLayer> cursorLayer;
0127     };
0128 
0129     WaylandBackend *m_backend;
0130     std::map<Output *, Layers> m_outputs;
0131 };
0132 
0133 } // namespace Wayland
0134 } // namespace KWin