File indexing completed on 2024-05-19 16:34:34

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 
0008     SPDX-License-Identifier: GPL-2.0-or-later
0009 */
0010 #pragma once
0011 
0012 // kwin
0013 #include "kwingltexture.h"
0014 #include "kwinglutils_funcs.h"
0015 #include <kwinglutils_export.h>
0016 
0017 // Qt
0018 #include <QSize>
0019 #include <QStack>
0020 
0021 /** @addtogroup kwineffects */
0022 /** @{ */
0023 
0024 class QVector2D;
0025 class QVector3D;
0026 class QVector4D;
0027 class QMatrix4x4;
0028 
0029 template<class K, class V>
0030 class QHash;
0031 
0032 namespace KWin
0033 {
0034 
0035 class GLVertexBuffer;
0036 class GLVertexBufferPrivate;
0037 
0038 // Initializes OpenGL stuff. This includes resolving function pointers as
0039 //  well as checking for GL version and extensions
0040 //  Note that GL context has to be created by the time this function is called
0041 typedef void (*resolveFuncPtr)();
0042 void KWINGLUTILS_EXPORT initGL(const std::function<resolveFuncPtr(const char *)> &resolveFunction);
0043 // Cleans up all resources hold by the GL Context
0044 void KWINGLUTILS_EXPORT cleanupGL();
0045 
0046 bool KWINGLUTILS_EXPORT hasGLVersion(int major, int minor, int release = 0);
0047 // use for both OpenGL and GLX extensions
0048 bool KWINGLUTILS_EXPORT hasGLExtension(const QByteArray &extension);
0049 
0050 // detect OpenGL error (add to various places in code to pinpoint the place)
0051 bool KWINGLUTILS_EXPORT checkGLError(const char *txt);
0052 
0053 QList<QByteArray> KWINGLUTILS_EXPORT openGLExtensions();
0054 
0055 class KWINGLUTILS_EXPORT GLShader
0056 {
0057 public:
0058     enum Flags {
0059         NoFlags = 0,
0060         ExplicitLinking = (1 << 0)
0061     };
0062 
0063     GLShader(const QString &vertexfile, const QString &fragmentfile, unsigned int flags = NoFlags);
0064     ~GLShader();
0065 
0066     bool isValid() const
0067     {
0068         return mValid;
0069     }
0070 
0071     void bindAttributeLocation(const char *name, int index);
0072     void bindFragDataLocation(const char *name, int index);
0073 
0074     bool link();
0075 
0076     int uniformLocation(const char *name);
0077 
0078     bool setUniform(const char *name, float value);
0079     bool setUniform(const char *name, int value);
0080     bool setUniform(const char *name, const QVector2D &value);
0081     bool setUniform(const char *name, const QVector3D &value);
0082     bool setUniform(const char *name, const QVector4D &value);
0083     bool setUniform(const char *name, const QMatrix4x4 &value);
0084     bool setUniform(const char *name, const QColor &color);
0085 
0086     bool setUniform(int location, float value);
0087     bool setUniform(int location, int value);
0088     bool setUniform(int location, const QVector2D &value);
0089     bool setUniform(int location, const QVector3D &value);
0090     bool setUniform(int location, const QVector4D &value);
0091     bool setUniform(int location, const QMatrix4x4 &value);
0092     bool setUniform(int location, const QColor &value);
0093 
0094     int attributeLocation(const char *name);
0095     bool setAttribute(const char *name, float value);
0096     /**
0097      * @return The value of the uniform as a matrix
0098      * @since 4.7
0099      */
0100     QMatrix4x4 getUniformMatrix4x4(const char *name);
0101 
0102     enum MatrixUniform {
0103         TextureMatrix = 0,
0104         ProjectionMatrix,
0105         ModelViewMatrix,
0106         ModelViewProjectionMatrix,
0107         WindowTransformation,
0108         ScreenTransformation,
0109         MatrixCount
0110     };
0111 
0112     enum Vec2Uniform {
0113         Offset,
0114         Vec2UniformCount
0115     };
0116 
0117     enum Vec4Uniform {
0118         ModulationConstant,
0119         Vec4UniformCount
0120     };
0121 
0122     enum FloatUniform {
0123         Saturation,
0124         FloatUniformCount
0125     };
0126 
0127     enum IntUniform {
0128         AlphaToOne, ///< @deprecated no longer used
0129         TextureWidth,
0130         TextureHeight,
0131         IntUniformCount
0132     };
0133 
0134     enum ColorUniform {
0135         Color,
0136         ColorUniformCount
0137     };
0138 
0139     bool setUniform(MatrixUniform uniform, const QMatrix4x4 &matrix);
0140     bool setUniform(Vec2Uniform uniform, const QVector2D &value);
0141     bool setUniform(Vec4Uniform uniform, const QVector4D &value);
0142     bool setUniform(FloatUniform uniform, float value);
0143     bool setUniform(IntUniform uniform, int value);
0144     bool setUniform(ColorUniform uniform, const QVector4D &value);
0145     bool setUniform(ColorUniform uniform, const QColor &value);
0146 
0147 protected:
0148     GLShader(unsigned int flags = NoFlags);
0149     bool loadFromFiles(const QString &vertexfile, const QString &fragmentfile);
0150     bool load(const QByteArray &vertexSource, const QByteArray &fragmentSource);
0151     const QByteArray prepareSource(GLenum shaderType, const QByteArray &sourceCode) const;
0152     bool compile(GLuint program, GLenum shaderType, const QByteArray &sourceCode) const;
0153     void bind();
0154     void unbind();
0155     void resolveLocations();
0156 
0157 private:
0158     unsigned int mProgram;
0159     bool mValid : 1;
0160     bool mLocationsResolved : 1;
0161     bool mExplicitLinking : 1;
0162     int mMatrixLocation[MatrixCount];
0163     int mVec2Location[Vec2UniformCount];
0164     int mVec4Location[Vec4UniformCount];
0165     int mFloatLocation[FloatUniformCount];
0166     int mIntLocation[IntUniformCount];
0167     int mColorLocation[ColorUniformCount];
0168 
0169     friend class ShaderManager;
0170 };
0171 
0172 enum class ShaderTrait {
0173     MapTexture = (1 << 0),
0174     UniformColor = (1 << 1),
0175     Modulate = (1 << 2),
0176     AdjustSaturation = (1 << 3),
0177 };
0178 
0179 Q_DECLARE_FLAGS(ShaderTraits, ShaderTrait)
0180 
0181 /**
0182  * @short Manager for Shaders.
0183  *
0184  * This class provides some built-in shaders to be used by both compositing scene and effects.
0185  * The ShaderManager provides methods to bind a built-in or a custom shader and keeps track of
0186  * the shaders which have been bound. When a shader is unbound the previously bound shader
0187  * will be rebound.
0188  *
0189  * @author Martin Gräßlin <mgraesslin@kde.org>
0190  * @since 4.7
0191  */
0192 class KWINGLUTILS_EXPORT ShaderManager
0193 {
0194 public:
0195     ~ShaderManager();
0196 
0197     /**
0198      * Returns a shader with the given traits, creating it if necessary.
0199      */
0200     GLShader *shader(ShaderTraits traits);
0201 
0202     /**
0203      * @return The currently bound shader or @c null if no shader is bound.
0204      */
0205     GLShader *getBoundShader() const;
0206 
0207     /**
0208      * @return @c true if a shader is bound, @c false otherwise
0209      */
0210     bool isShaderBound() const;
0211 
0212     /**
0213      * Pushes the current shader onto the stack and binds a shader
0214      * with the given traits.
0215      */
0216     GLShader *pushShader(ShaderTraits traits);
0217 
0218     /**
0219      * Binds the @p shader.
0220      * To unbind the shader use popShader. A previous bound shader will be rebound.
0221      * To bind a built-in shader use the more specific method.
0222      * @param shader The shader to be bound
0223      * @see popShader
0224      */
0225     void pushShader(GLShader *shader);
0226 
0227     /**
0228      * Unbinds the currently bound shader and rebinds a previous stored shader.
0229      * If there is no previous shader, no shader will be rebound.
0230      * It is not safe to call this method if there is no bound shader.
0231      * @see pushShader
0232      * @see getBoundShader
0233      */
0234     void popShader();
0235 
0236     /**
0237      * Creates a GLShader with the specified sources.
0238      * The difference to GLShader is that it does not need to be loaded from files.
0239      * @param vertexSource The source code of the vertex shader
0240      * @param fragmentSource The source code of the fragment shader.
0241      * @return The created shader
0242      */
0243     std::unique_ptr<GLShader> loadShaderFromCode(const QByteArray &vertexSource, const QByteArray &fragmentSource);
0244 
0245     /**
0246      * Creates a custom shader with the given @p traits and custom @p vertexSource and or @p fragmentSource.
0247      * If the @p vertexSource is empty a vertex shader with the given @p traits is generated.
0248      * If it is not empty the @p vertexSource is used as the source for the vertex shader.
0249      *
0250      * The same applies for argument @p fragmentSource just for the fragment shader.
0251      *
0252      * So if both @p vertesSource and @p fragmentSource are provided the @p traits are ignored.
0253      * If neither are provided a new shader following the @p traits is generated.
0254      *
0255      * @param traits The shader traits for generating the shader
0256      * @param vertexSource optional vertex shader source code to be used instead of shader traits
0257      * @param fragmentSource optional fragment shader source code to be used instead of shader traits
0258      * @return new generated shader
0259      * @since 5.6
0260      */
0261     std::unique_ptr<GLShader> generateCustomShader(ShaderTraits traits, const QByteArray &vertexSource = QByteArray(), const QByteArray &fragmentSource = QByteArray());
0262 
0263     /**
0264      * Creates a custom shader with the given @p traits and custom @p vertexFile and or @p fragmentFile.
0265      *
0266      * If the @p vertexFile is empty a vertex shader with the given @p traits is generated.
0267      * If it is not empty the @p vertexFile is used as the source for the vertex shader.
0268      *
0269      * The same applies for argument @p fragmentFile just for the fragment shader.
0270      *
0271      * So if both @p vertexFile and @p fragmentFile are provided the @p traits are ignored.
0272      * If neither are provided a new shader following the @p traits is generated.
0273      *
0274      * If a custom shader stage is provided and core profile is used, the final file path will
0275      * be resolved by appending "_core" to the basename.
0276      *
0277      * @param traits The shader traits for generating the shader
0278      * @param vertexFile optional vertex shader source code to be used instead of shader traits
0279      * @param fragmentFile optional fragment shader source code to be used instead of shader traits
0280      * @return new generated shader
0281      * @see generateCustomShader
0282      */
0283     std::unique_ptr<GLShader> generateShaderFromFile(ShaderTraits traits, const QString &vertexFile = QString(), const QString &fragmentFile = QString());
0284 
0285     /**
0286      * @return a pointer to the ShaderManager instance
0287      */
0288     static ShaderManager *instance();
0289 
0290     /**
0291      * @internal
0292      */
0293     static void cleanup();
0294 
0295 private:
0296     ShaderManager();
0297 
0298     void bindFragDataLocations(GLShader *shader);
0299     void bindAttributeLocations(GLShader *shader) const;
0300 
0301     QByteArray generateVertexSource(ShaderTraits traits) const;
0302     QByteArray generateFragmentSource(ShaderTraits traits) const;
0303     std::unique_ptr<GLShader> generateShader(ShaderTraits traits);
0304 
0305     QStack<GLShader *> m_boundShaders;
0306     std::map<ShaderTraits, std::unique_ptr<GLShader>> m_shaderHash;
0307     static std::unique_ptr<ShaderManager> s_shaderManager;
0308 };
0309 
0310 /**
0311  * An helper class to push a Shader on to ShaderManager's stack and ensuring that the Shader
0312  * gets popped again from the stack automatically once the object goes out of life.
0313  *
0314  * How to use:
0315  * @code
0316  * {
0317  * GLShader *myCustomShaderIWantToPush;
0318  * ShaderBinder binder(myCustomShaderIWantToPush);
0319  * // do stuff with the shader being pushed on the stack
0320  * }
0321  * // here the Shader is automatically popped as helper does no longer exist.
0322  * @endcode
0323  *
0324  * @since 4.10
0325  */
0326 class KWINGLUTILS_EXPORT ShaderBinder
0327 {
0328 public:
0329     /**
0330      * @brief Pushes the given @p shader to the ShaderManager's stack.
0331      *
0332      * @param shader The Shader to push on the stack
0333      * @see ShaderManager::pushShader
0334      */
0335     explicit ShaderBinder(GLShader *shader);
0336     /**
0337      * @brief Pushes the Shader with the given @p traits to the ShaderManager's stack.
0338      *
0339      * @param traits The traits describing the shader
0340      * @see ShaderManager::pushShader
0341      * @since 5.6
0342      */
0343     explicit ShaderBinder(ShaderTraits traits);
0344     ~ShaderBinder();
0345 
0346     /**
0347      * @return The Shader pushed to the Stack.
0348      */
0349     GLShader *shader();
0350 
0351 private:
0352     GLShader *m_shader;
0353 };
0354 
0355 inline ShaderBinder::ShaderBinder(GLShader *shader)
0356     : m_shader(shader)
0357 {
0358     ShaderManager::instance()->pushShader(shader);
0359 }
0360 
0361 inline ShaderBinder::ShaderBinder(ShaderTraits traits)
0362     : m_shader(nullptr)
0363 {
0364     m_shader = ShaderManager::instance()->pushShader(traits);
0365 }
0366 
0367 inline ShaderBinder::~ShaderBinder()
0368 {
0369     ShaderManager::instance()->popShader();
0370 }
0371 
0372 inline GLShader *ShaderBinder::shader()
0373 {
0374     return m_shader;
0375 }
0376 
0377 /**
0378  * @short OpenGL framebuffer object
0379  *
0380  * Framebuffer object enables you to render onto a texture. This texture can
0381  * later be used to e.g. do post-processing of the scene.
0382  *
0383  * @author Rivo Laks <rivolaks@hot.ee>
0384  */
0385 class KWINGLUTILS_EXPORT GLFramebuffer
0386 {
0387 public:
0388     /**
0389      * Constructs a GLFramebuffer
0390      * @since 5.13
0391      */
0392     explicit GLFramebuffer();
0393 
0394     /**
0395      * Constructs a GLFramebuffer. Note that ensuring the color attachment outlives
0396      * the framebuffer is the responsibility of the caller.
0397      *
0398      * @param colorAttachment texture where the scene will be rendered onto
0399      */
0400     explicit GLFramebuffer(GLTexture *colorAttachment);
0401 
0402     /**
0403      * Constructs a wrapper for an already created framebuffer object. The GLFramebuffer
0404      * does not take the ownership of the framebuffer object handle.
0405      */
0406     GLFramebuffer(GLuint handle, const QSize &size);
0407     ~GLFramebuffer();
0408 
0409     /**
0410      * Returns the framebuffer object handle to this framebuffer object.
0411      */
0412     GLuint handle() const
0413     {
0414         return mFramebuffer;
0415     }
0416     /**
0417      * Returns the size of the color attachment to this framebuffer object.
0418      */
0419     QSize size() const
0420     {
0421         return mSize;
0422     }
0423     bool valid() const
0424     {
0425         return mValid;
0426     }
0427 
0428     static void initStatic();
0429     static bool supported()
0430     {
0431         return sSupported;
0432     }
0433 
0434     /**
0435      * Returns the last bound framebuffer, or @c null if no framebuffer is current.
0436      */
0437     static GLFramebuffer *currentFramebuffer();
0438 
0439     /**
0440      * Pushes the framebuffer stack of the input parameter in reverse order.
0441      * @param fbos The stack of GLFramebuffers
0442      * @since 5.13
0443      */
0444     static void pushFramebuffers(QStack<GLFramebuffer *> fbos);
0445 
0446     static void pushFramebuffer(GLFramebuffer *fbo);
0447     static GLFramebuffer *popFramebuffer();
0448     /**
0449      * Whether the GL_EXT_framebuffer_blit extension is supported.
0450      * This functionality is not available in OpenGL ES 2.0.
0451      *
0452      * @returns whether framebuffer blitting is supported.
0453      * @since 4.8
0454      */
0455     static bool blitSupported();
0456 
0457     /**
0458      * Blits from @a source rectangle in the current framebuffer to the @a destination rectangle in
0459      * this framebuffer.
0460      *
0461      * Be aware that framebuffer blitting may not be supported on all hardware. Use blitSupported()
0462      * to check whether it is supported.
0463      *
0464      * The @a source and the @a destination rectangles can have different sizes. The @a filter indicates
0465      * what filter will be used in case scaling needs to be performed.
0466      *
0467      * @see blitSupported
0468      * @since 4.8
0469      */
0470     void blitFromFramebuffer(const QRect &source = QRect(), const QRect &destination = QRect(), GLenum filter = GL_LINEAR);
0471 
0472 protected:
0473     void initFBO(GLTexture *colorAttachment);
0474 
0475 private:
0476     bool bind();
0477 
0478     friend void KWin::cleanupGL();
0479     static void cleanup();
0480     static bool sSupported;
0481     static bool s_blitSupported;
0482     static QStack<GLFramebuffer *> s_fbos;
0483 
0484     GLuint mFramebuffer = 0;
0485     QSize mSize;
0486     bool mValid = false;
0487     bool mForeign = false;
0488 };
0489 
0490 enum VertexAttributeType {
0491     VA_Position = 0,
0492     VA_TexCoord = 1,
0493     VertexAttributeCount = 2,
0494 };
0495 
0496 /**
0497  * Describes the format of a vertex attribute stored in a buffer object.
0498  *
0499  * The attribute format consists of the attribute index, the number of
0500  * vector components, the data type, and the offset of the first element
0501  * relative to the start of the vertex data.
0502  */
0503 struct GLVertexAttrib
0504 {
0505     int index; /** The attribute index */
0506     int size; /** The number of components [1..4] */
0507     GLenum type; /** The type (e.g. GL_FLOAT) */
0508     int relativeOffset; /** The relative offset of the attribute */
0509 };
0510 
0511 /**
0512  * @short Vertex Buffer Object
0513  *
0514  * This is a short helper class to use vertex buffer objects (VBO). A VBO can be used to buffer
0515  * vertex data and to store them on graphics memory. It is the only allowed way to pass vertex
0516  * data to the GPU in OpenGL ES 2 and OpenGL 3 with forward compatible mode.
0517  *
0518  * If VBOs are not supported on the used OpenGL profile this class falls back to legacy
0519  * rendering using client arrays. Therefore this class should always be used for rendering geometries.
0520  *
0521  * @author Martin Gräßlin <mgraesslin@kde.org>
0522  * @since 4.6
0523  */
0524 class KWINGLUTILS_EXPORT GLVertexBuffer
0525 {
0526 public:
0527     /**
0528      * Enum to define how often the vertex data in the buffer object changes.
0529      */
0530     enum UsageHint {
0531         Dynamic, ///< frequent changes, but used several times for rendering
0532         Static, ///< No changes to data
0533         Stream ///< Data only used once for rendering, updated very frequently
0534     };
0535 
0536     explicit GLVertexBuffer(UsageHint hint);
0537     ~GLVertexBuffer();
0538 
0539     /**
0540      * Specifies how interleaved vertex attributes are laid out in
0541      * the buffer object.
0542      *
0543      * Note that the attributes and the stride should be 32 bit aligned
0544      * or a performance penalty may be incurred.
0545      *
0546      * For some hardware the optimal stride is a multiple of 32 bytes.
0547      *
0548      * Example:
0549      *
0550      *     struct Vertex {
0551      *         QVector3D position;
0552      *         QVector2D texcoord;
0553      *     };
0554      *
0555      *     const GLVertexAttrib attribs[] = {
0556      *         { VA_Position, 3, GL_FLOAT, offsetof(Vertex, position) },
0557      *         { VA_TexCoord, 2, GL_FLOAT, offsetof(Vertex, texcoord) }
0558      *     };
0559      *
0560      *     Vertex vertices[6];
0561      *     vbo->setAttribLayout(attribs, 2, sizeof(Vertex));
0562      *     vbo->setData(vertices, sizeof(vertices));
0563      */
0564     void setAttribLayout(const GLVertexAttrib *attribs, int count, int stride);
0565 
0566     /**
0567      * Uploads data into the buffer object's data store.
0568      */
0569     void setData(const void *data, size_t sizeInBytes);
0570 
0571     /**
0572      * Sets the number of vertices that will be drawn by the render() method.
0573      */
0574     void setVertexCount(int count);
0575 
0576     /**
0577      * Sets the vertex data.
0578      * @param numberVertices The number of vertices in the arrays
0579      * @param dim The dimension of the vertices: 2 for x/y, 3 for x/y/z
0580      * @param vertices The vertices, size must equal @a numberVertices * @a dim
0581      * @param texcoords The texture coordinates for each vertex.
0582      * Size must equal 2 * @a numberVertices.
0583      */
0584     void setData(int numberVertices, int dim, const float *vertices, const float *texcoords);
0585 
0586     /**
0587      * Maps an unused range of the data store into the client's address space.
0588      *
0589      * The data store will be reallocated if it is smaller than the given size.
0590      *
0591      * The buffer object is mapped for writing, not reading. Attempts to read from
0592      * the mapped buffer range may result in system errors, including program
0593      * termination. The data in the mapped region is undefined until it has been
0594      * written to. If subsequent GL calls access unwritten memory, the results are
0595      * undefined and system errors, including program termination, may occur.
0596      *
0597      * No GL calls that access the buffer object must be made while the buffer
0598      * object is mapped. The returned pointer must not be passed as a parameter
0599      * value to any GL function.
0600      *
0601      * It is assumed that the GL_ARRAY_BUFFER_BINDING will not be changed while
0602      * the buffer object is mapped.
0603      */
0604     GLvoid *map(size_t size);
0605 
0606     /**
0607      * Flushes the mapped buffer range and unmaps the buffer.
0608      */
0609     void unmap();
0610 
0611     /**
0612      * Binds the vertex arrays to the context.
0613      */
0614     void bindArrays();
0615 
0616     /**
0617      * Disables the vertex arrays.
0618      */
0619     void unbindArrays();
0620 
0621     /**
0622      * Draws count vertices beginning with first.
0623      */
0624     void draw(GLenum primitiveMode, int first, int count);
0625 
0626     /**
0627      * Draws count vertices beginning with first.
0628      */
0629     void draw(const QRegion &region, GLenum primitiveMode, int first, int count, bool hardwareClipping = false);
0630 
0631     /**
0632      * Renders the vertex data in given @a primitiveMode.
0633      * Please refer to OpenGL documentation of glDrawArrays or glDrawElements for allowed
0634      * values for @a primitiveMode. Best is to use GL_TRIANGLES or similar to be future
0635      * compatible.
0636      */
0637     void render(GLenum primitiveMode);
0638     /**
0639      * Same as above restricting painting to @a region if @a hardwareClipping is true.
0640      * It's within the caller's responsibility to enable GL_SCISSOR_TEST.
0641      */
0642     void render(const QRegion &region, GLenum primitiveMode, bool hardwareClipping = false);
0643     /**
0644      * Sets the color the geometry will be rendered with.
0645      * For legacy rendering glColor is used before rendering the geometry.
0646      * For core shader a uniform "geometryColor" is expected and is set.
0647      * @param color The color to render the geometry
0648      * @param enableColor Whether the geometry should be rendered with a color or not
0649      * @see setUseColor
0650      * @see isUseColor
0651      * @since 4.7
0652      */
0653     void setColor(const QColor &color, bool enableColor = true);
0654     /**
0655      * @return @c true if geometry will be painted with a color, @c false otherwise
0656      * @see setUseColor
0657      * @see setColor
0658      * @since 4.7
0659      */
0660     bool isUseColor() const;
0661     /**
0662      * Enables/Disables rendering the geometry with a color.
0663      * If no color is set an opaque, black color is used.
0664      * @param enable Enable/Disable rendering with color
0665      * @see isUseColor
0666      * @see setColor
0667      * @since 4.7
0668      */
0669     void setUseColor(bool enable);
0670 
0671     /**
0672      * Resets the instance to default values.
0673      * Useful for shared buffers.
0674      * @since 4.7
0675      */
0676     void reset();
0677 
0678     /**
0679      * Notifies the vertex buffer that we are done painting the frame.
0680      *
0681      * @internal
0682      */
0683     void endOfFrame();
0684 
0685     /**
0686      * Notifies the vertex buffer that we are about to paint a frame.
0687      *
0688      * @internal
0689      */
0690     void beginFrame();
0691 
0692     /**
0693      * @internal
0694      */
0695     static void initStatic();
0696 
0697     /**
0698      * @internal
0699      */
0700     static void cleanup();
0701 
0702     /**
0703      * Returns true if indexed quad mode is supported, and false otherwise.
0704      */
0705     static bool supportsIndexedQuads();
0706 
0707     /**
0708      * @return A shared VBO for streaming data
0709      * @since 4.7
0710      */
0711     static GLVertexBuffer *streamingBuffer();
0712 
0713     static const GLVertexAttrib GLVertex2DLayout[2];
0714     static const GLVertexAttrib GLVertex3DLayout[2];
0715 
0716 private:
0717     const std::unique_ptr<GLVertexBufferPrivate> d;
0718 };
0719 
0720 } // namespace
0721 
0722 Q_DECLARE_OPERATORS_FOR_FLAGS(KWin::ShaderTraits)
0723 
0724 /** @} */