/* KWin - the KDE window manager This file is part of the KDE project. SPDX-FileCopyrightText: 2013 Martin Gräßlin SPDX-FileCopyrightText: 2019 Roman Gilg SPDX-License-Identifier: GPL-2.0-or-later */ #pragma once #include "core/outputlayer.h" #include "opengl/eglnativefence.h" #include "platformsupport/scenes/opengl/abstract_egl_backend.h" #include "utils/damagejournal.h" #include struct wl_buffer; namespace KWin { class EglSwapchainSlot; class EglSwapchain; class GLFramebuffer; class GraphicsBufferAllocator; class GLRenderTimeQuery; namespace Wayland { class WaylandBackend; class WaylandOutput; class WaylandEglBackend; class WaylandEglPrimaryLayer : public OutputLayer { public: WaylandEglPrimaryLayer(WaylandOutput *output, WaylandEglBackend *backend); ~WaylandEglPrimaryLayer() override; GLFramebuffer *fbo() const; std::shared_ptr texture() const; void present(); std::optional doBeginFrame() override; bool doEndFrame(const QRegion &renderedRegion, const QRegion &damagedRegion, OutputFrame *frame) override; bool doImportScanoutBuffer(GraphicsBuffer *buffer, const ColorDescription &color, RenderingIntent intent, const std::shared_ptr &frame) override; DrmDevice *scanoutDevice() const override; QHash> supportedDrmFormats() const override; private: DamageJournal m_damageJournal; std::shared_ptr m_swapchain; std::shared_ptr m_buffer; std::unique_ptr m_query; WaylandEglBackend *const m_backend; wl_buffer *m_presentationBuffer = nullptr; friend class WaylandEglBackend; }; class WaylandEglCursorLayer : public OutputLayer { Q_OBJECT public: WaylandEglCursorLayer(WaylandOutput *output, WaylandEglBackend *backend); ~WaylandEglCursorLayer() override; std::optional doBeginFrame() override; bool doEndFrame(const QRegion &renderedRegion, const QRegion &damagedRegion, OutputFrame *frame) override; DrmDevice *scanoutDevice() const override; QHash> supportedDrmFormats() const override; private: WaylandEglBackend *m_backend; std::shared_ptr m_swapchain; std::shared_ptr m_buffer; std::unique_ptr m_query; }; /** * @brief OpenGL Backend using Egl on a Wayland surface. * * This Backend is the basis for a session compositor running on top of a Wayland system compositor. * It creates a Surface as large as the screen and maps it as a fullscreen shell surface on the * system compositor. The OpenGL context is created on the Wayland surface, so for rendering X11 is * not involved. * * Also in repainting the backend is currently still rather limited. Only supported mode is fullscreen * repaints, which is obviously not optimal. Best solution is probably to go for buffer_age extension * and make it the only available solution next to fullscreen repaints. */ class WaylandEglBackend : public AbstractEglBackend { Q_OBJECT public: WaylandEglBackend(WaylandBackend *b); ~WaylandEglBackend() override; WaylandBackend *backend() const; DrmDevice *drmDevice() const override; std::unique_ptr createSurfaceTextureWayland(SurfacePixmap *pixmap) override; void init() override; bool present(Output *output, const std::shared_ptr &frame) override; OutputLayer *primaryLayer(Output *output) override; OutputLayer *cursorLayer(Output *output) override; std::pair, ColorDescription> textureForOutput(KWin::Output *output) const override; private: bool initializeEgl(); bool initRenderingContext(); bool createEglWaylandOutput(Output *output); void cleanupSurfaces() override; struct Layers { std::unique_ptr primaryLayer; std::unique_ptr cursorLayer; }; WaylandBackend *m_backend; std::map m_outputs; }; } // namespace Wayland } // namespace KWin