File indexing completed on 2024-05-19 16:34:37

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2006 Lubos Lunak <l.lunak@kde.org>
0006     SPDX-FileCopyrightText: 2009, 2010, 2011 Martin Gräßlin <mgraesslin@kde.org>
0007 
0008     SPDX-License-Identifier: GPL-2.0-or-later
0009 */
0010 #pragma once
0011 
0012 #include "core/renderbackend.h"
0013 
0014 #include <QRegion>
0015 #include <memory>
0016 
0017 namespace KWin
0018 {
0019 class Output;
0020 class OpenGLBackend;
0021 class GLTexture;
0022 
0023 /**
0024  * @brief The OpenGLBackend creates and holds the OpenGL context and is responsible for Texture from Pixmap.
0025  *
0026  * The OpenGLBackend is an abstract base class used by the SceneOpenGL to abstract away the differences
0027  * between various OpenGL windowing systems such as GLX and EGL.
0028  *
0029  * A concrete implementation has to create and release the OpenGL context in a way so that the
0030  * SceneOpenGL does not have to care about it.
0031  *
0032  * In addition a major task for this class is to generate the SceneOpenGLTexturePrivate which is
0033  * able to perform the texture from pixmap operation in the given backend.
0034  *
0035  * @author Martin Gräßlin <mgraesslin@kde.org>
0036  */
0037 class KWIN_EXPORT OpenGLBackend : public RenderBackend
0038 {
0039     Q_OBJECT
0040 
0041 public:
0042     OpenGLBackend();
0043     virtual ~OpenGLBackend();
0044 
0045     virtual void init() = 0;
0046     CompositingType compositingType() const override final;
0047     bool checkGraphicsReset() override final;
0048 
0049     virtual bool makeCurrent() = 0;
0050     virtual void doneCurrent() = 0;
0051 
0052     /**
0053      * @brief Whether the creation of the Backend failed.
0054      *
0055      * The SceneOpenGL should test whether the Backend got constructed correctly. If this method
0056      * returns @c true, the SceneOpenGL should not try to start the rendering.
0057      *
0058      * @return bool @c true if the creation of the Backend failed, @c false otherwise.
0059      */
0060     bool isFailed() const
0061     {
0062         return m_failed;
0063     }
0064     /**
0065      * @brief Whether the backend uses direct rendering.
0066      *
0067      * Some OpenGLScene modes require direct rendering. E.g. the OpenGL 2 should not be used
0068      * if direct rendering is not supported by the Scene.
0069      *
0070      * @return bool @c true if the GL context is direct, @c false if indirect
0071      */
0072     bool isDirectRendering() const
0073     {
0074         return m_directRendering;
0075     }
0076 
0077     bool supportsBufferAge() const
0078     {
0079         return m_haveBufferAge;
0080     }
0081 
0082     bool supportsPartialUpdate() const
0083     {
0084         return m_havePartialUpdate;
0085     }
0086     bool supportsSwapBuffersWithDamage() const
0087     {
0088         return m_haveSwapBuffersWithDamage;
0089     }
0090 
0091     bool supportsNativeFence() const
0092     {
0093         return m_haveNativeFence;
0094     }
0095 
0096     /**
0097      * The backend specific extensions (e.g. EGL/GLX extensions).
0098      *
0099      * Not the OpenGL (ES) extension!
0100      */
0101     QList<QByteArray> extensions() const
0102     {
0103         return m_extensions;
0104     }
0105 
0106     /**
0107      * @returns whether the backend specific extensions contains @p extension.
0108      */
0109     bool hasExtension(const QByteArray &extension) const
0110     {
0111         return m_extensions.contains(extension);
0112     }
0113 
0114     /**
0115      * Copy a region of pixels from the current read to the current draw buffer
0116      */
0117     void copyPixels(const QRegion &region, const QSize &screenSize);
0118 
0119     virtual std::shared_ptr<GLTexture> textureForOutput(Output *output) const;
0120 
0121 protected:
0122     /**
0123      * @brief Sets the backend initialization to failed.
0124      *
0125      * This method should be called by the concrete subclass in case the initialization failed.
0126      * The given @p reason is logged as a warning.
0127      *
0128      * @param reason The reason why the initialization failed.
0129      */
0130     void setFailed(const QString &reason);
0131     /**
0132      * @brief Sets whether the OpenGL context is direct.
0133      *
0134      * Should be called by the concrete subclass once it is determined whether the OpenGL context is
0135      * direct or indirect.
0136      * If the subclass does not call this method, the backend defaults to @c false.
0137      *
0138      * @param direct @c true if the OpenGL context is direct, @c false if indirect
0139      */
0140     void setIsDirectRendering(bool direct)
0141     {
0142         m_directRendering = direct;
0143     }
0144 
0145     void setSupportsBufferAge(bool value)
0146     {
0147         m_haveBufferAge = value;
0148     }
0149 
0150     void setSupportsPartialUpdate(bool value)
0151     {
0152         m_havePartialUpdate = value;
0153     }
0154 
0155     void setSupportsSwapBuffersWithDamage(bool value)
0156     {
0157         m_haveSwapBuffersWithDamage = value;
0158     }
0159 
0160     void setSupportsNativeFence(bool value)
0161     {
0162         m_haveNativeFence = value;
0163     }
0164 
0165     /**
0166      * Sets the platform-specific @p extensions.
0167      *
0168      * These are the EGL/GLX extensions, not the OpenGL extensions
0169      */
0170     void setExtensions(const QList<QByteArray> &extensions)
0171     {
0172         m_extensions = extensions;
0173     }
0174 
0175 private:
0176     /**
0177      * @brief Whether direct rendering is used, defaults to @c false.
0178      */
0179     bool m_directRendering;
0180     /**
0181      * @brief Whether the backend supports GLX_EXT_buffer_age / EGL_EXT_buffer_age.
0182      */
0183     bool m_haveBufferAge;
0184     /**
0185      * @brief Whether the backend supports EGL_KHR_partial_update
0186      */
0187     bool m_havePartialUpdate = false;
0188     bool m_haveSwapBuffersWithDamage = false;
0189     /**
0190      * @brief Whether the backend supports EGL_ANDROID_native_fence_sync.
0191      */
0192     bool m_haveNativeFence = false;
0193     /**
0194      * @brief Whether the initialization failed, of course default to @c false.
0195      */
0196     bool m_failed;
0197     QList<QByteArray> m_extensions;
0198 };
0199 
0200 }