File indexing completed on 2024-05-12 05:31:41

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2006-2007 Rivo Laks <rivolaks@hot.ee>
0006     SPDX-FileCopyrightText: 2010, 2011 Martin Gräßlin <mgraesslin@kde.org>
0007     SPDX-FileCopyrightText: 2023 Xaver Hugl <xaver.hugl@kde.org>
0008 
0009     SPDX-License-Identifier: GPL-2.0-or-later
0010 */
0011 #pragma once
0012 #include "kwin_export.h"
0013 
0014 #include <QRect>
0015 #include <QStack>
0016 #include <epoxy/gl.h>
0017 
0018 namespace KWin
0019 {
0020 
0021 class GLTexture;
0022 class RenderTarget;
0023 class RenderViewport;
0024 
0025 // Cleans up all resources hold by the GL Context
0026 void KWIN_EXPORT cleanupGL();
0027 
0028 /**
0029  * @short OpenGL framebuffer object
0030  *
0031  * Framebuffer object enables you to render onto a texture. This texture can
0032  * later be used to e.g. do post-processing of the scene.
0033  *
0034  * @author Rivo Laks <rivolaks@hot.ee>
0035  */
0036 class KWIN_EXPORT GLFramebuffer
0037 {
0038 public:
0039     enum Attachment {
0040         NoAttachment,
0041         CombinedDepthStencil,
0042     };
0043 
0044     /**
0045      * Constructs a GLFramebuffer
0046      * @since 5.13
0047      */
0048     explicit GLFramebuffer();
0049 
0050     /**
0051      * Constructs a GLFramebuffer. Note that ensuring the color attachment outlives
0052      * the framebuffer is the responsibility of the caller.
0053      *
0054      * @param colorAttachment texture where the scene will be rendered onto
0055      */
0056     explicit GLFramebuffer(GLTexture *colorAttachment, Attachment attachment = NoAttachment);
0057 
0058     /**
0059      * Constructs a wrapper for an already created framebuffer object. The GLFramebuffer
0060      * does not take the ownership of the framebuffer object handle.
0061      */
0062     GLFramebuffer(GLuint handle, const QSize &size);
0063     ~GLFramebuffer();
0064 
0065     /**
0066      * Returns the framebuffer object handle to this framebuffer object.
0067      */
0068     GLuint handle() const
0069     {
0070         return m_handle;
0071     }
0072     /**
0073      * Returns the size of the color attachment to this framebuffer object.
0074      */
0075     QSize size() const
0076     {
0077         return m_size;
0078     }
0079     bool valid() const
0080     {
0081         return m_valid;
0082     }
0083 
0084     static void initStatic();
0085     static bool supported()
0086     {
0087         return s_supported;
0088     }
0089 
0090     /**
0091      * Returns the last bound framebuffer, or @c null if no framebuffer is current.
0092      */
0093     static GLFramebuffer *currentFramebuffer();
0094 
0095     static void pushFramebuffer(GLFramebuffer *fbo);
0096     static GLFramebuffer *popFramebuffer();
0097     /**
0098      * Whether the GL_EXT_framebuffer_blit extension is supported.
0099      * This functionality is not available in OpenGL ES 2.0.
0100      *
0101      * @returns whether framebuffer blitting is supported.
0102      * @since 4.8
0103      */
0104     static bool blitSupported();
0105 
0106     /**
0107      * Blits from @a source rectangle in the current framebuffer to the @a destination rectangle in
0108      * this framebuffer.
0109      *
0110      * Be aware that framebuffer blitting may not be supported on all hardware. Use blitSupported()
0111      * to check whether it is supported.
0112      *
0113      * The @a source and the @a destination rectangles can have different sizes. The @a filter indicates
0114      * what filter will be used in case scaling needs to be performed.
0115      *
0116      * @see blitSupported
0117      * @since 4.8
0118      */
0119     void blitFromFramebuffer(const QRect &source = QRect(), const QRect &destination = QRect(), GLenum filter = GL_LINEAR, bool flipX = false, bool flipY = false);
0120 
0121     /**
0122      * Blits from @a source rectangle in logical coordinates in the current framebuffer to the @a destination rectangle in texture-local coordinates
0123      * in this framebuffer, taking into account any transformations the source render target may have
0124      */
0125     bool blitFromRenderTarget(const RenderTarget &sourceRenderTarget, const RenderViewport &sourceViewport, const QRect &source, const QRect &destination);
0126 
0127     /**
0128      * @returns the color attachment of this fbo. May be nullptr
0129      */
0130     GLTexture *colorAttachment() const;
0131 
0132 protected:
0133     void initColorAttachment(GLTexture *colorAttachment);
0134     void initDepthStencilAttachment();
0135 
0136 private:
0137     bool bind();
0138 
0139     friend void KWin::cleanupGL();
0140     static void cleanup();
0141     inline static bool s_supported = false;
0142     inline static bool s_supportsPackedDepthStencil = false;
0143     inline static bool s_supportsDepth24 = false;
0144     inline static bool s_blitSupported = false;
0145     inline static QStack<GLFramebuffer *> s_fbos;
0146 
0147     GLuint m_handle = 0;
0148     GLuint m_depthBuffer = 0;
0149     GLuint m_stencilBuffer = 0;
0150     QSize m_size;
0151     bool m_valid = false;
0152     bool m_foreign = false;
0153     GLTexture *const m_colorAttachment;
0154 };
0155 
0156 }