diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6487663805..7f0bde7b19 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -42,6 +42,7 @@ target_sources(kwin PRIVATE core/gbmgraphicsbufferallocator.cpp core/graphicsbuffer.cpp core/graphicsbufferallocator.cpp + core/graphicsbufferview.cpp core/inputbackend.cpp core/inputdevice.cpp core/output.cpp diff --git a/src/core/graphicsbuffer.cpp b/src/core/graphicsbuffer.cpp index d46352e7a6..be7a9b5dd3 100644 --- a/src/core/graphicsbuffer.cpp +++ b/src/core/graphicsbuffer.cpp @@ -53,6 +53,15 @@ void GraphicsBuffer::drop() } } +void *GraphicsBuffer::map() +{ + return nullptr; +} + +void GraphicsBuffer::unmap() +{ +} + const DmaBufAttributes *GraphicsBuffer::dmabufAttributes() const { return nullptr; diff --git a/src/core/graphicsbuffer.h b/src/core/graphicsbuffer.h index fe03e717a6..38a57f7af3 100644 --- a/src/core/graphicsbuffer.h +++ b/src/core/graphicsbuffer.h @@ -58,6 +58,9 @@ public: void unref(); void drop(); + virtual void *map(); + virtual void unmap(); + virtual QSize size() const = 0; virtual bool hasAlphaChannel() const = 0; diff --git a/src/core/graphicsbufferview.cpp b/src/core/graphicsbufferview.cpp new file mode 100644 index 0000000000..e78e098ecf --- /dev/null +++ b/src/core/graphicsbufferview.cpp @@ -0,0 +1,91 @@ +/* + SPDX-FileCopyrightText: 2023 Vlad Zahorodnii + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#include "core/graphicsbufferview.h" +#include "core/graphicsbuffer.h" +#include "utils/common.h" + +#include + +namespace KWin +{ + +static QImage::Format drmFormatToQImageFormat(uint32_t drmFormat) +{ + switch (drmFormat) { +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + case DRM_FORMAT_ABGR16161616: + return QImage::Format_RGBA64_Premultiplied; + case DRM_FORMAT_XBGR16161616: + return QImage::Format_RGBX64; + case DRM_FORMAT_ARGB2101010: + return QImage::Format_A2RGB30_Premultiplied; + case DRM_FORMAT_XRGB2101010: + return QImage::Format_RGB30; + case DRM_FORMAT_ABGR2101010: + return QImage::Format_A2BGR30_Premultiplied; + case DRM_FORMAT_XBGR2101010: + return QImage::Format_BGR30; +#endif + case DRM_FORMAT_ARGB8888: + return QImage::Format_ARGB32_Premultiplied; + case DRM_FORMAT_XRGB8888: + return QImage::Format_RGB32; + default: + return QImage::Format_Invalid; + } +} + +GraphicsBufferView::GraphicsBufferView(GraphicsBuffer *buffer) + : m_buffer(buffer) +{ + int width; + int height; + int stride; + int format; + + if (auto dmabuf = buffer->dmabufAttributes()) { + if (dmabuf->planeCount != 1) { + return; + } + width = dmabuf->width; + height = dmabuf->height; + stride = dmabuf->pitch[0]; + format = dmabuf->format; + } else if (auto shm = buffer->shmAttributes()) { + width = shm->size.width(); + height = shm->size.height(); + stride = shm->stride; + format = shm->format; + } else { + qCWarning(KWIN_CORE) << "Cannot create a graphics buffer view for unknown buffer type" << buffer; + return; + } + + void *data = buffer->map(); + if (data) { + m_image = QImage(static_cast(data), width, height, stride, drmFormatToQImageFormat(format)); + } +} + +GraphicsBufferView::~GraphicsBufferView() +{ + if (!m_image.isNull()) { + m_buffer->unmap(); + } +} + +QImage *GraphicsBufferView::image() +{ + return &m_image; +} + +const QImage *GraphicsBufferView::image() const +{ + return &m_image; +} + +} // namespace KWin diff --git a/src/core/graphicsbufferview.h b/src/core/graphicsbufferview.h new file mode 100644 index 0000000000..a12f1b24f6 --- /dev/null +++ b/src/core/graphicsbufferview.h @@ -0,0 +1,32 @@ +/* + SPDX-FileCopyrightText: 2023 Vlad Zahorodnii + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#pragma once + +#include "kwin_export.h" + +#include + +namespace KWin +{ + +class GraphicsBuffer; + +class KWIN_EXPORT GraphicsBufferView +{ +public: + explicit GraphicsBufferView(GraphicsBuffer *buffer); + ~GraphicsBufferView(); + + QImage *image(); + const QImage *image() const; + +private: + GraphicsBuffer *m_buffer; + QImage m_image; +}; + +} // namespace KWin