File indexing completed on 2024-11-10 04:56:35

0001 /*
0002     SPDX-FileCopyrightText: 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #pragma once
0008 
0009 #include "core/outputlayer.h"
0010 #include "options.h"
0011 #include "platformsupport/scenes/opengl/abstract_egl_backend.h"
0012 #include "platformsupport/scenes/opengl/openglsurfacetexture_x11.h"
0013 #include "utils/damagejournal.h"
0014 
0015 #include "opengl/gltexture.h"
0016 #include "opengl/gltexture_p.h"
0017 
0018 typedef struct _XDisplay Display;
0019 
0020 namespace KWin
0021 {
0022 
0023 class EglPixmapTexturePrivate;
0024 class SoftwareVsyncMonitor;
0025 class X11StandaloneBackend;
0026 class EglBackend;
0027 class GLRenderTimeQuery;
0028 
0029 class EglLayer : public OutputLayer
0030 {
0031 public:
0032     EglLayer(EglBackend *backend);
0033 
0034     std::optional<OutputLayerBeginFrameInfo> beginFrame() override;
0035     bool endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override;
0036     std::chrono::nanoseconds queryRenderTime() const override;
0037 
0038 private:
0039     EglBackend *const m_backend;
0040 };
0041 
0042 class EglBackend : public AbstractEglBackend
0043 {
0044     Q_OBJECT
0045 
0046 public:
0047     EglBackend(::Display *display, X11StandaloneBackend *platform);
0048     ~EglBackend() override;
0049 
0050     void init() override;
0051 
0052     std::unique_ptr<SurfaceTexture> createSurfaceTextureX11(SurfacePixmapX11 *texture) override;
0053     OutputLayerBeginFrameInfo beginFrame();
0054     void endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion);
0055     void present(Output *output, const std::shared_ptr<OutputFrame> &frame) override;
0056     OverlayWindow *overlayWindow() const override;
0057     OutputLayer *primaryLayer(Output *output) override;
0058     std::chrono::nanoseconds queryRenderTime();
0059 
0060 protected:
0061     EGLConfig chooseBufferConfig();
0062     bool initRenderingContext();
0063 
0064 private:
0065     void screenGeometryChanged();
0066     void presentSurface(EGLSurface surface, const QRegion &damage, const QRect &screenGeometry);
0067     void vblank(std::chrono::nanoseconds timestamp);
0068     EGLSurface createSurface(xcb_window_t window);
0069 
0070     X11StandaloneBackend *m_backend;
0071     std::unique_ptr<SoftwareVsyncMonitor> m_vsyncMonitor;
0072     std::unique_ptr<OverlayWindow> m_overlayWindow;
0073     DamageJournal m_damageJournal;
0074     std::unique_ptr<GLFramebuffer> m_fbo;
0075     int m_bufferAge = 0;
0076     QRegion m_lastRenderedRegion;
0077     std::unique_ptr<EglLayer> m_layer;
0078     std::unique_ptr<GLRenderTimeQuery> m_query;
0079     int m_havePostSubBuffer = false;
0080     bool m_havePlatformBase = false;
0081     Options::GlSwapStrategy m_swapStrategy = Options::AutoSwapStrategy;
0082     std::shared_ptr<OutputFrame> m_frame;
0083 };
0084 
0085 class EglPixmapTexture : public GLTexture
0086 {
0087 public:
0088     explicit EglPixmapTexture(EglBackend *backend);
0089     ~EglPixmapTexture() override;
0090 
0091     bool create(SurfacePixmapX11 *texture);
0092 
0093 private:
0094     void onDamage() override;
0095 
0096     EglBackend *const m_backend;
0097     EGLImageKHR m_image = EGL_NO_IMAGE_KHR;
0098 };
0099 
0100 class EglSurfaceTextureX11 : public OpenGLSurfaceTextureX11
0101 {
0102 public:
0103     EglSurfaceTextureX11(EglBackend *backend, SurfacePixmapX11 *texture);
0104 
0105     bool create() override;
0106     void update(const QRegion &region) override;
0107 };
0108 
0109 } // namespace KWin