File indexing completed on 2025-04-27 11:33:00
0001 /* 0002 KWin - the KDE window manager 0003 This file is part of the KDE project. 0004 0005 SPDX-FileCopyrightText: 2012 Martin Gräßlin <mgraesslin@kde.org> 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 #pragma once 0010 #include "core/outputlayer.h" 0011 #include "openglbackend.h" 0012 #include "openglsurfacetexture_x11.h" 0013 #include "utils/damagejournal.h" 0014 #include "x11eventfilter.h" 0015 0016 #include <epoxy/glx.h> 0017 #include <fixx11h.h> 0018 #include <xcb/glx.h> 0019 0020 #include <kwingltexture.h> 0021 #include <kwingltexture_p.h> 0022 0023 #include <QHash> 0024 #include <memory> 0025 0026 namespace KWin 0027 { 0028 0029 class GlxPixmapTexturePrivate; 0030 class VsyncMonitor; 0031 class X11StandaloneBackend; 0032 class GlxBackend; 0033 0034 // GLX_MESA_swap_interval 0035 using glXSwapIntervalMESA_func = int (*)(unsigned int interval); 0036 extern glXSwapIntervalMESA_func glXSwapIntervalMESA; 0037 0038 class FBConfigInfo 0039 { 0040 public: 0041 GLXFBConfig fbconfig; 0042 int bind_texture_format; 0043 int texture_targets; 0044 int y_inverted; 0045 int mipmap; 0046 }; 0047 0048 // ------------------------------------------------------------------ 0049 0050 class SwapEventFilter : public X11EventFilter 0051 { 0052 public: 0053 SwapEventFilter(xcb_drawable_t drawable, xcb_glx_drawable_t glxDrawable); 0054 bool event(xcb_generic_event_t *event) override; 0055 0056 private: 0057 xcb_drawable_t m_drawable; 0058 xcb_glx_drawable_t m_glxDrawable; 0059 }; 0060 0061 class GlxLayer : public OutputLayer 0062 { 0063 public: 0064 GlxLayer(GlxBackend *backend); 0065 0066 std::optional<OutputLayerBeginFrameInfo> beginFrame() override; 0067 bool endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override; 0068 0069 private: 0070 GlxBackend *const m_backend; 0071 }; 0072 0073 /** 0074 * @brief OpenGL Backend using GLX over an X overlay window. 0075 */ 0076 class GlxBackend : public OpenGLBackend 0077 { 0078 Q_OBJECT 0079 0080 public: 0081 GlxBackend(Display *display, X11StandaloneBackend *backend); 0082 ~GlxBackend() override; 0083 std::unique_ptr<SurfaceTexture> createSurfaceTextureX11(SurfacePixmapX11 *pixmap) override; 0084 OutputLayerBeginFrameInfo beginFrame(); 0085 void endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion); 0086 void present(Output *output) override; 0087 bool makeCurrent() override; 0088 void doneCurrent() override; 0089 OverlayWindow *overlayWindow() const override; 0090 void init() override; 0091 OutputLayer *primaryLayer(Output *output) override; 0092 0093 Display *display() const 0094 { 0095 return m_x11Display; 0096 } 0097 0098 private: 0099 void vblank(std::chrono::nanoseconds timestamp); 0100 void present(const QRegion &damage); 0101 bool initBuffer(); 0102 bool checkVersion(); 0103 void initExtensions(); 0104 bool initRenderingContext(); 0105 bool initFbConfig(); 0106 void initVisualDepthHashTable(); 0107 void setSwapInterval(int interval); 0108 void screenGeometryChanged(); 0109 0110 int visualDepth(xcb_visualid_t visual) const; 0111 const FBConfigInfo &infoForVisual(xcb_visualid_t visual); 0112 0113 /** 0114 * @brief The OverlayWindow used by this Backend. 0115 */ 0116 std::unique_ptr<OverlayWindow> m_overlayWindow; 0117 ::Window window; 0118 GLXFBConfig fbconfig; 0119 GLXWindow glxWindow; 0120 GLXContext ctx; 0121 QHash<xcb_visualid_t, FBConfigInfo> m_fbconfigHash; 0122 QHash<xcb_visualid_t, int> m_visualDepthHash; 0123 std::unique_ptr<SwapEventFilter> m_swapEventFilter; 0124 std::unique_ptr<GLFramebuffer> m_fbo; 0125 DamageJournal m_damageJournal; 0126 QRegion m_lastRenderedRegion; 0127 int m_bufferAge; 0128 bool m_haveMESACopySubBuffer = false; 0129 bool m_haveMESASwapControl = false; 0130 bool m_haveEXTSwapControl = false; 0131 bool m_haveSGISwapControl = false; 0132 Display *m_x11Display; 0133 X11StandaloneBackend *m_backend; 0134 std::unique_ptr<VsyncMonitor> m_vsyncMonitor; 0135 std::unique_ptr<GlxLayer> m_layer; 0136 friend class GlxPixmapTexturePrivate; 0137 }; 0138 0139 class GlxPixmapTexture final : public GLTexture 0140 { 0141 public: 0142 explicit GlxPixmapTexture(GlxBackend *backend); 0143 0144 bool create(SurfacePixmapX11 *texture); 0145 0146 private: 0147 Q_DECLARE_PRIVATE(GlxPixmapTexture) 0148 }; 0149 0150 class GlxPixmapTexturePrivate final : public GLTexturePrivate 0151 { 0152 public: 0153 GlxPixmapTexturePrivate(GlxPixmapTexture *texture, GlxBackend *backend); 0154 ~GlxPixmapTexturePrivate() override; 0155 0156 bool create(SurfacePixmapX11 *texture); 0157 0158 protected: 0159 void onDamage() override; 0160 0161 private: 0162 GlxBackend *m_backend; 0163 GlxPixmapTexture *q; 0164 GLXPixmap m_glxPixmap; 0165 }; 0166 0167 class GlxSurfaceTextureX11 final : public OpenGLSurfaceTextureX11 0168 { 0169 public: 0170 GlxSurfaceTextureX11(GlxBackend *backend, SurfacePixmapX11 *pixmap); 0171 0172 bool create() override; 0173 void update(const QRegion ®ion) override; 0174 }; 0175 0176 } // namespace