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 #include "core/graphicsbufferview.h"
0008 #include "core/graphicsbuffer.h"
0009 #include "utils/common.h"
0010 
0011 #include <drm_fourcc.h>
0012 
0013 namespace KWin
0014 {
0015 
0016 static QImage::Format drmFormatToQImageFormat(uint32_t drmFormat)
0017 {
0018     switch (drmFormat) {
0019 #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
0020     case DRM_FORMAT_ABGR16161616:
0021         return QImage::Format_RGBA64_Premultiplied;
0022     case DRM_FORMAT_XBGR16161616:
0023         return QImage::Format_RGBX64;
0024     case DRM_FORMAT_ARGB2101010:
0025         return QImage::Format_A2RGB30_Premultiplied;
0026     case DRM_FORMAT_XRGB2101010:
0027         return QImage::Format_RGB30;
0028     case DRM_FORMAT_ABGR2101010:
0029         return QImage::Format_A2BGR30_Premultiplied;
0030     case DRM_FORMAT_XBGR2101010:
0031         return QImage::Format_BGR30;
0032 #endif
0033     case DRM_FORMAT_ARGB8888:
0034         return QImage::Format_ARGB32_Premultiplied;
0035     case DRM_FORMAT_XRGB8888:
0036         return QImage::Format_RGB32;
0037     default:
0038         return QImage::Format_Invalid;
0039     }
0040 }
0041 
0042 GraphicsBufferView::GraphicsBufferView(GraphicsBuffer *buffer, GraphicsBuffer::MapFlags accessFlags)
0043     : m_buffer(buffer)
0044 {
0045     int width;
0046     int height;
0047     int format;
0048 
0049     if (auto dmabuf = buffer->dmabufAttributes()) {
0050         if (dmabuf->planeCount != 1) {
0051             return;
0052         }
0053         width = dmabuf->width;
0054         height = dmabuf->height;
0055         format = dmabuf->format;
0056     } else if (auto shm = buffer->shmAttributes()) {
0057         width = shm->size.width();
0058         height = shm->size.height();
0059         format = shm->format;
0060     } else {
0061         qCWarning(KWIN_CORE) << "Cannot create a graphics buffer view for unknown buffer type" << buffer;
0062         return;
0063     }
0064 
0065     const auto [data, stride] = buffer->map(accessFlags);
0066     if (data) {
0067         m_image = QImage(static_cast<uchar *>(data), width, height, stride, drmFormatToQImageFormat(format));
0068     }
0069 }
0070 
0071 GraphicsBufferView::~GraphicsBufferView()
0072 {
0073     if (!m_image.isNull()) {
0074         m_buffer->unmap();
0075     }
0076 }
0077 
0078 bool GraphicsBufferView::isNull() const
0079 {
0080     return m_image.isNull();
0081 }
0082 
0083 QImage *GraphicsBufferView::image()
0084 {
0085     return &m_image;
0086 }
0087 
0088 const QImage *GraphicsBufferView::image() const
0089 {
0090     return &m_image;
0091 }
0092 
0093 } // namespace KWin