File indexing completed on 2024-11-10 04:56:34

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 "platformsupport/scenes/qpainter/qpainterbackend.h"
0014 #include "utils/damagejournal.h"
0015 
0016 #include <QImage>
0017 #include <QObject>
0018 #include <chrono>
0019 
0020 namespace KWin
0021 {
0022 class Output;
0023 class GraphicsBufferAllocator;
0024 class QPainterSwapchainSlot;
0025 class QPainterSwapchain;
0026 
0027 namespace Wayland
0028 {
0029 class WaylandBackend;
0030 class WaylandDisplay;
0031 class WaylandOutput;
0032 class WaylandQPainterBackend;
0033 
0034 class WaylandQPainterPrimaryLayer : public OutputLayer
0035 {
0036 public:
0037     WaylandQPainterPrimaryLayer(WaylandOutput *output, WaylandQPainterBackend *backend);
0038     ~WaylandQPainterPrimaryLayer() override;
0039 
0040     std::optional<OutputLayerBeginFrameInfo> beginFrame() override;
0041     bool endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override;
0042     std::chrono::nanoseconds queryRenderTime() const override;
0043 
0044     void present();
0045 
0046     QRegion accumulateDamage(int bufferAge) const;
0047 
0048 private:
0049     WaylandOutput *m_waylandOutput;
0050     WaylandQPainterBackend *m_backend;
0051     DamageJournal m_damageJournal;
0052 
0053     std::unique_ptr<QPainterSwapchain> m_swapchain;
0054     std::shared_ptr<QPainterSwapchainSlot> m_back;
0055     std::chrono::steady_clock::time_point m_renderStart;
0056     std::chrono::nanoseconds m_renderTime;
0057 
0058     friend class WaylandQPainterBackend;
0059 };
0060 
0061 class WaylandQPainterCursorLayer : public OutputLayer
0062 {
0063     Q_OBJECT
0064 
0065 public:
0066     WaylandQPainterCursorLayer(WaylandOutput *output, WaylandQPainterBackend *backend);
0067     ~WaylandQPainterCursorLayer() override;
0068 
0069     std::optional<OutputLayerBeginFrameInfo> beginFrame() override;
0070     bool endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override;
0071     std::chrono::nanoseconds queryRenderTime() const override;
0072 
0073 private:
0074     WaylandOutput *m_output;
0075     WaylandQPainterBackend *m_backend;
0076     std::unique_ptr<QPainterSwapchain> m_swapchain;
0077     std::shared_ptr<QPainterSwapchainSlot> m_back;
0078     std::chrono::steady_clock::time_point m_renderStart;
0079     std::chrono::nanoseconds m_renderTime;
0080 };
0081 
0082 class WaylandQPainterBackend : public QPainterBackend
0083 {
0084     Q_OBJECT
0085 public:
0086     explicit WaylandQPainterBackend(WaylandBackend *b);
0087     ~WaylandQPainterBackend() override;
0088 
0089     GraphicsBufferAllocator *graphicsBufferAllocator() const override;
0090 
0091     void present(Output *output, const std::shared_ptr<OutputFrame> &frame) override;
0092     OutputLayer *primaryLayer(Output *output) override;
0093     OutputLayer *cursorLayer(Output *output) override;
0094 
0095 private:
0096     void createOutput(Output *waylandOutput);
0097 
0098     struct Layers
0099     {
0100         std::unique_ptr<WaylandQPainterPrimaryLayer> primaryLayer;
0101         std::unique_ptr<WaylandQPainterCursorLayer> cursorLayer;
0102     };
0103 
0104     WaylandBackend *m_backend;
0105     std::unique_ptr<GraphicsBufferAllocator> m_allocator;
0106     std::map<Output *, Layers> m_outputs;
0107 };
0108 
0109 } // namespace Wayland
0110 } // namespace KWin