1 /* 2 KWin - the KDE window manager 3 This file is part of the KDE project. 4 5 SPDX-FileCopyrightText: 2006 Lubos Lunak <l.lunak@kde.org> 6 SPDX-FileCopyrightText: 2009, 2010, 2011 Martin Gräßlin <mgraesslin@kde.org> 7 8 SPDX-License-Identifier: GPL-2.0-or-later 9 */ 10 #ifndef KWIN_SCENE_OPENGL_BACKEND_H 11 #define KWIN_SCENE_OPENGL_BACKEND_H 12 13 #include <QObject> 14 #include <QRegion> 15 16 #include <kwin_export.h> 17 18 namespace KWin 19 { 20 class AbstractOutput; 21 class OpenGLBackend; 22 class OverlayWindow; 23 class PlatformSurfaceTexture; 24 class SurfaceItem; 25 class SurfacePixmapInternal; 26 class SurfacePixmapX11; 27 class SurfacePixmapWayland; 28 class GLTexture; 29 30 /** 31 * @brief The OpenGLBackend creates and holds the OpenGL context and is responsible for Texture from Pixmap. 32 * 33 * The OpenGLBackend is an abstract base class used by the SceneOpenGL to abstract away the differences 34 * between various OpenGL windowing systems such as GLX and EGL. 35 * 36 * A concrete implementation has to create and release the OpenGL context in a way so that the 37 * SceneOpenGL does not have to care about it. 38 * 39 * In addition a major task for this class is to generate the SceneOpenGLTexturePrivate which is 40 * able to perform the texture from pixmap operation in the given backend. 41 * 42 * @author Martin Gräßlin <mgraesslin@kde.org> 43 */ 44 class KWIN_EXPORT OpenGLBackend : public QObject 45 { 46 Q_OBJECT 47 48 public: 49 OpenGLBackend(); 50 virtual ~OpenGLBackend(); 51 52 virtual void init() = 0; 53 54 virtual PlatformSurfaceTexture *createPlatformSurfaceTextureInternal(SurfacePixmapInternal *pixmap); 55 virtual PlatformSurfaceTexture *createPlatformSurfaceTextureX11(SurfacePixmapX11 *pixmap); 56 virtual PlatformSurfaceTexture *createPlatformSurfaceTextureWayland(SurfacePixmapWayland *pixmap); 57 58 /** 59 * Notifies about starting to paint. 60 * 61 * @p damage contains the reported damage as suggested by windows and effects on prepaint calls. 62 */ 63 virtual void aboutToStartPainting(AbstractOutput *output, const QRegion &damage); 64 virtual bool makeCurrent() = 0; 65 virtual void doneCurrent() = 0; 66 virtual QRegion beginFrame(AbstractOutput *output) = 0; 67 virtual void endFrame(AbstractOutput *output, const QRegion &damage, const QRegion &damagedRegion) = 0; 68 /** 69 * Tries to directly scan out a surface to the screen) 70 * @return if the scanout fails (or is not supported on the specified screen) 71 */ 72 virtual bool scanout(AbstractOutput *output, SurfaceItem *surfaceItem); 73 74 /** 75 * @brief Returns the OverlayWindow used by the backend. 76 * 77 * A backend does not have to use an OverlayWindow, this is mostly for the X world. 78 * In case the backend does not use an OverlayWindow it is allowed to return @c null. 79 * It's the task of the caller to check whether it is @c null. 80 * 81 * @return :OverlayWindow* 82 */ 83 virtual OverlayWindow *overlayWindow() const; 84 /** 85 * @brief Whether the creation of the Backend failed. 86 * 87 * The SceneOpenGL should test whether the Backend got constructed correctly. If this method 88 * returns @c true, the SceneOpenGL should not try to start the rendering. 89 * 90 * @return bool @c true if the creation of the Backend failed, @c false otherwise. 91 */ isFailed()92 bool isFailed() const { 93 return m_failed; 94 } 95 /** 96 * @brief Whether the backend uses direct rendering. 97 * 98 * Some OpenGLScene modes require direct rendering. E.g. the OpenGL 2 should not be used 99 * if direct rendering is not supported by the Scene. 100 * 101 * @return bool @c true if the GL context is direct, @c false if indirect 102 */ isDirectRendering()103 bool isDirectRendering() const { 104 return m_directRendering; 105 } 106 supportsBufferAge()107 bool supportsBufferAge() const { 108 return m_haveBufferAge; 109 } 110 supportsPartialUpdate()111 bool supportsPartialUpdate() const 112 { 113 return m_havePartialUpdate; 114 } supportsSwapBuffersWithDamage()115 bool supportsSwapBuffersWithDamage() const 116 { 117 return m_haveSwapBuffersWithDamage; 118 } 119 supportsNativeFence()120 bool supportsNativeFence() const 121 { 122 return m_haveNativeFence; 123 } 124 virtual bool directScanoutAllowed(AbstractOutput *output) const; 125 126 /** 127 * The backend specific extensions (e.g. EGL/GLX extensions). 128 * 129 * Not the OpenGL (ES) extension! 130 */ extensions()131 QList<QByteArray> extensions() const { 132 return m_extensions; 133 } 134 135 /** 136 * @returns whether the backend specific extensions contains @p extension. 137 */ hasExtension(const QByteArray & extension)138 bool hasExtension(const QByteArray &extension) const { 139 return m_extensions.contains(extension); 140 } 141 142 /** 143 * Copy a region of pixels from the current read to the current draw buffer 144 */ 145 void copyPixels(const QRegion ®ion); 146 147 virtual QSharedPointer<GLTexture> textureForOutput(AbstractOutput *output) const; 148 149 protected: 150 /** 151 * @brief Sets the backend initialization to failed. 152 * 153 * This method should be called by the concrete subclass in case the initialization failed. 154 * The given @p reason is logged as a warning. 155 * 156 * @param reason The reason why the initialization failed. 157 */ 158 void setFailed(const QString &reason); 159 /** 160 * @brief Sets whether the OpenGL context is direct. 161 * 162 * Should be called by the concrete subclass once it is determined whether the OpenGL context is 163 * direct or indirect. 164 * If the subclass does not call this method, the backend defaults to @c false. 165 * 166 * @param direct @c true if the OpenGL context is direct, @c false if indirect 167 */ setIsDirectRendering(bool direct)168 void setIsDirectRendering(bool direct) { 169 m_directRendering = direct; 170 } 171 setSupportsBufferAge(bool value)172 void setSupportsBufferAge(bool value) { 173 m_haveBufferAge = value; 174 } 175 setSupportsPartialUpdate(bool value)176 void setSupportsPartialUpdate(bool value) 177 { 178 m_havePartialUpdate = value; 179 } 180 setSupportsSwapBuffersWithDamage(bool value)181 void setSupportsSwapBuffersWithDamage(bool value) 182 { 183 m_haveSwapBuffersWithDamage = value; 184 } 185 setSupportsNativeFence(bool value)186 void setSupportsNativeFence(bool value) 187 { 188 m_haveNativeFence = value; 189 } 190 191 /** 192 * Sets the platform-specific @p extensions. 193 * 194 * These are the EGL/GLX extensions, not the OpenGL extensions 195 */ setExtensions(const QList<QByteArray> & extensions)196 void setExtensions(const QList<QByteArray> &extensions) { 197 m_extensions = extensions; 198 } 199 200 private: 201 /** 202 * @brief Whether direct rendering is used, defaults to @c false. 203 */ 204 bool m_directRendering; 205 /** 206 * @brief Whether the backend supports GLX_EXT_buffer_age / EGL_EXT_buffer_age. 207 */ 208 bool m_haveBufferAge; 209 /** 210 * @brief Whether the backend supports EGL_KHR_partial_update 211 */ 212 bool m_havePartialUpdate = false; 213 bool m_haveSwapBuffersWithDamage = false; 214 /** 215 * @brief Whether the backend supports EGL_ANDROID_native_fence_sync. 216 */ 217 bool m_haveNativeFence = false; 218 /** 219 * @brief Whether the initialization failed, of course default to @c false. 220 */ 221 bool m_failed; 222 QList<QByteArray> m_extensions; 223 }; 224 225 } 226 227 #endif 228