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 11 #ifndef KWIN_SCENE_OPENGL_H 12 #define KWIN_SCENE_OPENGL_H 13 14 #include "openglbackend.h" 15 16 #include "decorationitem.h" 17 #include "scene.h" 18 #include "shadow.h" 19 20 #include "kwinglutils.h" 21 22 namespace KWin 23 { 24 class LanczosFilter; 25 class OpenGLBackend; 26 27 class KWIN_EXPORT SceneOpenGL 28 : public Scene 29 { 30 Q_OBJECT 31 public: 32 class EffectFrame; 33 ~SceneOpenGL() override; 34 bool initFailed() const override; 35 void paint(AbstractOutput *output, const QRegion &damage, const QList<Toplevel *> &windows, 36 RenderLoop *renderLoop) override; 37 Scene::EffectFrame *createEffectFrame(EffectFrameImpl *frame) override; 38 Shadow *createShadow(Toplevel *toplevel) override; 39 OverlayWindow *overlayWindow() const override; 40 bool makeOpenGLContextCurrent() override; 41 void doneOpenGLContextCurrent() override; 42 bool supportsNativeFence() const override; 43 DecorationRenderer *createDecorationRenderer(Decoration::DecoratedClientImpl *impl) override; 44 virtual QMatrix4x4 projectionMatrix() const = 0; 45 bool animationsSupported() const override; 46 PlatformSurfaceTexture *createPlatformSurfaceTextureInternal(SurfacePixmapInternal *pixmap) override; 47 PlatformSurfaceTexture *createPlatformSurfaceTextureX11(SurfacePixmapX11 *pixmap) override; 48 PlatformSurfaceTexture *createPlatformSurfaceTextureWayland(SurfacePixmapWayland *pixmap) override; 49 debug()50 bool debug() const { return m_debug; } 51 void initDebugOutput(); 52 backend()53 OpenGLBackend *backend() const { 54 return m_backend; 55 } 56 57 QVector<QByteArray> openGLPlatformInterfaceExtensions() const override; 58 QSharedPointer<GLTexture> textureForOutput(AbstractOutput *output) const override; 59 60 static SceneOpenGL *createScene(QObject *parent); 61 62 protected: 63 SceneOpenGL(OpenGLBackend *backend, QObject *parent = nullptr); 64 void paintBackground(const QRegion ®ion) override; 65 void aboutToStartPainting(AbstractOutput *output, const QRegion &damage) override; 66 void extendPaintRegion(QRegion ®ion, bool opaqueFullscreen) override; 67 QMatrix4x4 transformation(int mask, const ScreenPaintData &data) const; 68 void paintDesktop(int desktop, int mask, const QRegion ®ion, ScreenPaintData &data) override; 69 void paintEffectQuickView(EffectQuickView *w) override; 70 71 void handleGraphicsReset(GLenum status); 72 73 virtual void doPaintBackground(const QVector<float> &vertices) = 0; 74 virtual void updateProjectionMatrix(const QRect &geometry) = 0; 75 76 protected: 77 bool init_ok; 78 private: 79 bool viewportLimitsMatched(const QSize &size) const; 80 81 private: 82 bool m_resetOccurred = false; 83 bool m_debug; 84 OpenGLBackend *m_backend; 85 }; 86 87 class SceneOpenGL2 : public SceneOpenGL 88 { 89 Q_OBJECT 90 public: 91 explicit SceneOpenGL2(OpenGLBackend *backend, QObject *parent = nullptr); 92 ~SceneOpenGL2() override; compositingType()93 CompositingType compositingType() const override { 94 return OpenGLCompositing; 95 } 96 97 static bool supported(OpenGLBackend *backend); 98 projectionMatrix()99 QMatrix4x4 projectionMatrix() const override { return m_projectionMatrix; } screenProjectionMatrix()100 QMatrix4x4 screenProjectionMatrix() const override { return m_screenProjectionMatrix; } 101 102 protected: 103 void paintSimpleScreen(int mask, const QRegion ®ion) override; 104 void paintGenericScreen(int mask, const ScreenPaintData &data) override; 105 void doPaintBackground(const QVector< float >& vertices) override; 106 Scene::Window *createWindow(Toplevel *t) override; 107 void finalDrawWindow(EffectWindowImpl* w, int mask, const QRegion ®ion, WindowPaintData& data) override; 108 void updateProjectionMatrix(const QRect &geometry) override; 109 void paintCursor(const QRegion ®ion) override; 110 111 private: 112 void performPaintWindow(EffectWindowImpl* w, int mask, const QRegion ®ion, WindowPaintData& data); 113 114 LanczosFilter *m_lanczosFilter; 115 QScopedPointer<GLTexture> m_cursorTexture; 116 bool m_cursorTextureDirty = false; 117 QMatrix4x4 m_projectionMatrix; 118 QMatrix4x4 m_screenProjectionMatrix; 119 GLuint vao; 120 }; 121 122 class OpenGLWindow final : public Scene::Window 123 { 124 Q_OBJECT 125 126 public: 127 struct RenderNode 128 { 129 GLTexture *texture = nullptr; 130 WindowQuadList quads; 131 QMatrix4x4 transformMatrix; 132 int firstVertex = 0; 133 int vertexCount = 0; 134 qreal opacity = 1; 135 bool hasAlpha = false; 136 TextureCoordinateType coordinateType = UnnormalizedCoordinates; 137 }; 138 139 struct RenderContext 140 { 141 QVector<RenderNode> renderNodes; 142 QStack<QMatrix4x4> transforms; 143 const QRegion clip; 144 const WindowPaintData &paintData; 145 const bool hardwareClipping; 146 }; 147 148 OpenGLWindow(Toplevel *toplevel, SceneOpenGL *scene); 149 ~OpenGLWindow() override; 150 151 void performPaint(int mask, const QRegion ®ion, const WindowPaintData &data) override; 152 QSharedPointer<GLTexture> windowTexture() override; 153 154 private: 155 QMatrix4x4 modelViewProjectionMatrix(int mask, const WindowPaintData &data) const; 156 QVector4D modulate(float opacity, float brightness) const; 157 void setBlendEnabled(bool enabled); 158 void createRenderNode(Item *item, RenderContext *context); 159 160 SceneOpenGL *m_scene; 161 bool m_blendingEnabled = false; 162 }; 163 164 class SceneOpenGL::EffectFrame 165 : public Scene::EffectFrame 166 { 167 public: 168 EffectFrame(EffectFrameImpl* frame, SceneOpenGL *scene); 169 ~EffectFrame() override; 170 171 void free() override; 172 void freeIconFrame() override; 173 void freeTextFrame() override; 174 void freeSelection() override; 175 176 void render(const QRegion ®ion, double opacity, double frameOpacity) override; 177 178 void crossFadeIcon() override; 179 void crossFadeText() override; 180 181 static void cleanup(); 182 183 private: 184 void updateTexture(); 185 void updateTextTexture(); 186 187 GLTexture *m_texture; 188 GLTexture *m_textTexture; 189 GLTexture *m_oldTextTexture; 190 QPixmap *m_textPixmap; // need to keep the pixmap around to workaround some driver problems 191 GLTexture *m_iconTexture; 192 GLTexture *m_oldIconTexture; 193 GLTexture *m_selectionTexture; 194 GLVertexBuffer *m_unstyledVBO; 195 SceneOpenGL *m_scene; 196 197 static GLTexture* m_unstyledTexture; 198 static QPixmap* m_unstyledPixmap; // need to keep the pixmap around to workaround some driver problems 199 static void updateUnstyledTexture(); // Update OpenGL unstyled frame texture 200 }; 201 202 /** 203 * @short OpenGL implementation of Shadow. 204 * 205 * This class extends Shadow by the Elements required for OpenGL rendering. 206 * @author Martin Gräßlin <mgraesslin@kde.org> 207 */ 208 class SceneOpenGLShadow 209 : public Shadow 210 { 211 public: 212 explicit SceneOpenGLShadow(Toplevel *toplevel); 213 ~SceneOpenGLShadow() override; 214 shadowTexture()215 GLTexture *shadowTexture() { 216 return m_texture.data(); 217 } 218 protected: 219 bool prepareBackend() override; 220 private: 221 QSharedPointer<GLTexture> m_texture; 222 }; 223 224 class SceneOpenGLDecorationRenderer : public DecorationRenderer 225 { 226 Q_OBJECT 227 public: 228 enum class DecorationPart : int { 229 Left, 230 Top, 231 Right, 232 Bottom, 233 Count 234 }; 235 explicit SceneOpenGLDecorationRenderer(Decoration::DecoratedClientImpl *client); 236 ~SceneOpenGLDecorationRenderer() override; 237 238 void render(const QRegion ®ion) override; 239 texture()240 GLTexture *texture() { 241 return m_texture.data(); 242 } texture()243 GLTexture *texture() const { 244 return m_texture.data(); 245 } 246 247 private: 248 void resizeTexture(); 249 QScopedPointer<GLTexture> m_texture; 250 }; 251 252 class KWIN_EXPORT OpenGLFactory : public SceneFactory 253 { 254 Q_OBJECT 255 Q_INTERFACES(KWin::SceneFactory) 256 Q_PLUGIN_METADATA(IID "org.kde.kwin.Scene" FILE "opengl.json") 257 258 public: 259 explicit OpenGLFactory(QObject *parent = nullptr); 260 ~OpenGLFactory() override; 261 262 Scene *create(QObject *parent = nullptr) const override; 263 }; 264 265 } // namespace 266 267 #endif 268