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

0001 /*
0002     SPDX-FileCopyrightText: 2023 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #pragma once
0008 
0009 #include "kwin_export.h"
0010 #include "utils/filedescriptor.h"
0011 
0012 #include <QObject>
0013 #include <QSize>
0014 #include <utility>
0015 
0016 namespace KWin
0017 {
0018 
0019 struct DmaBufAttributes
0020 {
0021     int planeCount = 0;
0022     int width = 0;
0023     int height = 0;
0024     uint32_t format = 0;
0025     uint64_t modifier = 0;
0026 
0027     std::array<FileDescriptor, 4> fd;
0028     std::array<uint32_t, 4> offset{0, 0, 0, 0};
0029     std::array<uint32_t, 4> pitch{0, 0, 0, 0};
0030 };
0031 
0032 struct ShmAttributes
0033 {
0034     FileDescriptor fd;
0035     int stride;
0036     off_t offset;
0037     QSize size;
0038     uint32_t format;
0039 };
0040 
0041 /**
0042  * This enum type is used to describe where the origin lies in a graphics buffer.
0043  */
0044 enum class GraphicsBufferOrigin {
0045     TopLeft,
0046     BottomLeft,
0047 };
0048 
0049 /**
0050  * The GraphicsBuffer class represents a chunk of memory containing graphics data.
0051  *
0052  * A graphics buffer can be referenced. In which case, it won't be destroyed until all
0053  * references are dropped. You can use the isDropped() function to check whether the
0054  * buffer has been marked as destroyed.
0055  */
0056 class KWIN_EXPORT GraphicsBuffer : public QObject
0057 {
0058     Q_OBJECT
0059 
0060 public:
0061     explicit GraphicsBuffer(QObject *parent = nullptr);
0062 
0063     bool isReferenced() const;
0064     bool isDropped() const;
0065 
0066     void ref();
0067     void unref();
0068     void drop();
0069 
0070     enum MapFlag {
0071         Read = 0x1,
0072         Write = 0x2,
0073     };
0074     Q_DECLARE_FLAGS(MapFlags, MapFlag)
0075 
0076     struct Map
0077     {
0078         void *data = nullptr;
0079         uint32_t stride = 0;
0080     };
0081     virtual Map map(MapFlags flags);
0082     virtual void unmap();
0083 
0084     virtual QSize size() const = 0;
0085     virtual bool hasAlphaChannel() const = 0;
0086 
0087     virtual const DmaBufAttributes *dmabufAttributes() const;
0088     virtual const ShmAttributes *shmAttributes() const;
0089 
0090     static bool alphaChannelFromDrmFormat(uint32_t format);
0091 
0092 Q_SIGNALS:
0093     void released();
0094 
0095 protected:
0096     int m_refCount = 0;
0097     bool m_dropped = false;
0098 };
0099 
0100 /**
0101  * The GraphicsBufferRef type holds a reference to a GraphicsBuffer. While the reference
0102  * exists, the graphics buffer cannot be destroyed and the client cannnot modify it.
0103  */
0104 class GraphicsBufferRef
0105 {
0106 public:
0107     GraphicsBufferRef()
0108         : m_buffer(nullptr)
0109     {
0110     }
0111 
0112     GraphicsBufferRef(GraphicsBuffer *buffer)
0113         : m_buffer(buffer)
0114     {
0115         if (m_buffer) {
0116             m_buffer->ref();
0117         }
0118     }
0119 
0120     GraphicsBufferRef(const GraphicsBufferRef &other)
0121         : m_buffer(other.m_buffer)
0122     {
0123         if (m_buffer) {
0124             m_buffer->unref();
0125         }
0126     }
0127 
0128     GraphicsBufferRef(GraphicsBufferRef &&other)
0129         : m_buffer(std::exchange(other.m_buffer, nullptr))
0130     {
0131     }
0132 
0133     ~GraphicsBufferRef()
0134     {
0135         if (m_buffer) {
0136             m_buffer->unref();
0137         }
0138     }
0139 
0140     GraphicsBufferRef &operator=(const GraphicsBufferRef &other)
0141     {
0142         if (other.m_buffer) {
0143             other.m_buffer->ref();
0144         }
0145         if (m_buffer) {
0146             m_buffer->unref();
0147         }
0148         m_buffer = other.m_buffer;
0149         return *this;
0150     }
0151 
0152     GraphicsBufferRef &operator=(GraphicsBufferRef &&other)
0153     {
0154         if (m_buffer) {
0155             m_buffer->unref();
0156         }
0157         m_buffer = std::exchange(other.m_buffer, nullptr);
0158         return *this;
0159     }
0160 
0161     GraphicsBufferRef &operator=(GraphicsBuffer *buffer)
0162     {
0163         if (m_buffer != buffer) {
0164             if (m_buffer) {
0165                 m_buffer->unref();
0166             }
0167             if (buffer) {
0168                 buffer->ref();
0169             }
0170             m_buffer = buffer;
0171         }
0172         return *this;
0173     }
0174 
0175     inline GraphicsBuffer *buffer() const
0176     {
0177         return m_buffer;
0178     }
0179 
0180     inline GraphicsBuffer *operator*() const
0181     {
0182         return m_buffer;
0183     }
0184 
0185     inline GraphicsBuffer *operator->() const
0186     {
0187         return m_buffer;
0188     }
0189 
0190     inline operator bool() const
0191     {
0192         return m_buffer;
0193     }
0194 
0195 private:
0196     GraphicsBuffer *m_buffer;
0197 };
0198 
0199 } // namespace KWin
0200 
0201 Q_DECLARE_OPERATORS_FOR_FLAGS(KWin::GraphicsBuffer::MapFlags)