File indexing completed on 2026-05-17 05:38:35

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2013 Martin Gräßlin <mgraesslin@kde.org>
0006     SPDX-FileCopyrightText: 2019 Roman Gilg <subdiff@gmail.com>
0007 
0008     SPDX-License-Identifier: GPL-2.0-or-later
0009 */
0010 #pragma once
0011 
0012 #include "core/outputlayer.h"
0013 #include "platformsupport/scenes/opengl/abstract_egl_backend.h"
0014 #include "utils/damagejournal.h"
0015 
0016 #include <memory>
0017 
0018 namespace KWin
0019 {
0020 class EglSwapchainSlot;
0021 class EglSwapchain;
0022 class GLFramebuffer;
0023 class GraphicsBufferAllocator;
0024 class GLRenderTimeQuery;
0025 
0026 namespace Wayland
0027 {
0028 class WaylandBackend;
0029 class WaylandOutput;
0030 class WaylandEglBackend;
0031 
0032 class WaylandEglPrimaryLayer : public OutputLayer
0033 {
0034 public:
0035     WaylandEglPrimaryLayer(WaylandOutput *output, WaylandEglBackend *backend);
0036     ~WaylandEglPrimaryLayer() override;
0037 
0038     GLFramebuffer *fbo() const;
0039     std::shared_ptr<GLTexture> texture() const;
0040     void present();
0041 
0042     std::optional<OutputLayerBeginFrameInfo> beginFrame() override;
0043     bool endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override;
0044     std::chrono::nanoseconds queryRenderTime() const override;
0045 
0046 private:
0047     WaylandOutput *m_waylandOutput;
0048     DamageJournal m_damageJournal;
0049     std::shared_ptr<EglSwapchain> m_swapchain;
0050     std::shared_ptr<EglSwapchainSlot> m_buffer;
0051     std::unique_ptr<GLRenderTimeQuery> m_query;
0052     WaylandEglBackend *const m_backend;
0053 
0054     friend class WaylandEglBackend;
0055 };
0056 
0057 class WaylandEglCursorLayer : public OutputLayer
0058 {
0059     Q_OBJECT
0060 
0061 public:
0062     WaylandEglCursorLayer(WaylandOutput *output, WaylandEglBackend *backend);
0063     ~WaylandEglCursorLayer() override;
0064 
0065     std::optional<OutputLayerBeginFrameInfo> beginFrame() override;
0066     bool endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override;
0067     std::chrono::nanoseconds queryRenderTime() const override;
0068 
0069 private:
0070     WaylandOutput *m_output;
0071     WaylandEglBackend *m_backend;
0072     std::shared_ptr<EglSwapchain> m_swapchain;
0073     std::shared_ptr<EglSwapchainSlot> m_buffer;
0074     std::unique_ptr<GLRenderTimeQuery> m_query;
0075 };
0076 
0077 /**
0078  * @brief OpenGL Backend using Egl on a Wayland surface.
0079  *
0080  * This Backend is the basis for a session compositor running on top of a Wayland system compositor.
0081  * It creates a Surface as large as the screen and maps it as a fullscreen shell surface on the
0082  * system compositor. The OpenGL context is created on the Wayland surface, so for rendering X11 is
0083  * not involved.
0084  *
0085  * Also in repainting the backend is currently still rather limited. Only supported mode is fullscreen
0086  * repaints, which is obviously not optimal. Best solution is probably to go for buffer_age extension
0087  * and make it the only available solution next to fullscreen repaints.
0088  */
0089 class WaylandEglBackend : public AbstractEglBackend
0090 {
0091     Q_OBJECT
0092 public:
0093     WaylandEglBackend(WaylandBackend *b);
0094     ~WaylandEglBackend() override;
0095 
0096     WaylandBackend *backend() const;
0097     GraphicsBufferAllocator *graphicsBufferAllocator() const override;
0098 
0099     std::unique_ptr<SurfaceTexture> createSurfaceTextureWayland(SurfacePixmap *pixmap) override;
0100 
0101     void init() override;
0102     void present(Output *output, const std::shared_ptr<OutputFrame> &frame) override;
0103     OutputLayer *primaryLayer(Output *output) override;
0104     OutputLayer *cursorLayer(Output *output) override;
0105 
0106     std::pair<std::shared_ptr<KWin::GLTexture>, ColorDescription> textureForOutput(KWin::Output *output) const override;
0107 
0108 private:
0109     bool initializeEgl();
0110     bool initRenderingContext();
0111     bool createEglWaylandOutput(Output *output);
0112     void cleanupSurfaces() override;
0113 
0114     struct Layers
0115     {
0116         std::unique_ptr<WaylandEglPrimaryLayer> primaryLayer;
0117         std::unique_ptr<WaylandEglCursorLayer> cursorLayer;
0118     };
0119 
0120     WaylandBackend *m_backend;
0121     std::unique_ptr<GraphicsBufferAllocator> m_allocator;
0122     std::map<Output *, Layers> m_outputs;
0123 };
0124 
0125 } // namespace Wayland
0126 } // namespace KWin