dmabuf: make use of FileDescriptor class
This commit is contained in:
parent
cb8be232a1
commit
6cd4d69644
20 changed files with 74 additions and 121 deletions
|
@ -658,16 +658,13 @@ std::shared_ptr<DmaBufTexture> DrmBackend::createDmaBufTexture(const QSize &size
|
|||
}
|
||||
|
||||
// The bo will be kept around until the last fd is closed.
|
||||
const DmaBufAttributes attributes = dmaBufAttributesForBo(bo);
|
||||
DmaBufAttributes attributes = dmaBufAttributesForBo(bo);
|
||||
gbm_bo_destroy(bo);
|
||||
const auto eglBackend = static_cast<EglGbmBackend *>(m_renderBackend);
|
||||
eglBackend->makeCurrent();
|
||||
if (auto texture = eglBackend->importDmaBufAsTexture(attributes)) {
|
||||
return std::make_shared<DmaBufTexture>(texture, attributes);
|
||||
return std::make_shared<DmaBufTexture>(texture, std::move(attributes));
|
||||
} else {
|
||||
for (int i = 0; i < attributes.planeCount; ++i) {
|
||||
::close(attributes.fd[i]);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -152,7 +152,7 @@ void GbmBuffer::createFds()
|
|||
|
||||
std::shared_ptr<GbmBuffer> GbmBuffer::importBuffer(DrmGpu *gpu, KWaylandServer::LinuxDmaBufV1ClientBuffer *clientBuffer)
|
||||
{
|
||||
const auto attrs = clientBuffer->attributes();
|
||||
const auto &attrs = clientBuffer->attributes();
|
||||
gbm_bo *bo;
|
||||
if (attrs.modifier != DRM_FORMAT_MOD_INVALID || attrs.offset[0] > 0 || attrs.planeCount > 1) {
|
||||
gbm_import_fd_modifier_data data = {};
|
||||
|
@ -162,14 +162,14 @@ std::shared_ptr<GbmBuffer> GbmBuffer::importBuffer(DrmGpu *gpu, KWaylandServer::
|
|||
data.num_fds = attrs.planeCount;
|
||||
data.modifier = attrs.modifier;
|
||||
for (int i = 0; i < attrs.planeCount; i++) {
|
||||
data.fds[i] = attrs.fd[i];
|
||||
data.fds[i] = attrs.fd[i].get();
|
||||
data.offsets[i] = attrs.offset[i];
|
||||
data.strides[i] = attrs.pitch[i];
|
||||
}
|
||||
bo = gbm_bo_import(gpu->gbmDevice(), GBM_BO_IMPORT_FD_MODIFIER, &data, GBM_BO_USE_SCANOUT);
|
||||
} else {
|
||||
gbm_import_fd_data data = {};
|
||||
data.fd = attrs.fd[0];
|
||||
data.fd = attrs.fd[0].get();
|
||||
data.width = static_cast<uint32_t>(attrs.width);
|
||||
data.height = static_cast<uint32_t>(attrs.height);
|
||||
data.stride = attrs.pitch[0];
|
||||
|
|
|
@ -58,7 +58,7 @@ void DmabufFeedback::scanoutFailed(KWaylandServer::SurfaceInterface *surface, co
|
|||
if (const auto &feedback = m_surface->dmabufFeedbackV1()) {
|
||||
const auto buffer = qobject_cast<KWaylandServer::LinuxDmaBufV1ClientBuffer *>(surface->buffer());
|
||||
Q_ASSERT(buffer);
|
||||
const DmaBufAttributes dmabufAttrs = buffer->attributes();
|
||||
const DmaBufAttributes &dmabufAttrs = buffer->attributes();
|
||||
if (!m_attemptedFormats[dmabufAttrs.format].contains(dmabufAttrs.modifier)) {
|
||||
m_attemptedFormats[dmabufAttrs.format] << dmabufAttrs.modifier;
|
||||
QVector<KWaylandServer::LinuxDmaBufV1Feedback::Tranche> scanoutTranches;
|
||||
|
|
|
@ -263,14 +263,7 @@ bool operator==(const GbmFormat &lhs, const GbmFormat &rhs)
|
|||
|
||||
EGLImageKHR EglGbmBackend::importBufferObjectAsImage(gbm_bo *bo)
|
||||
{
|
||||
const DmaBufAttributes dmabuf = dmaBufAttributesForBo(bo);
|
||||
EGLImage image = importDmaBufAsImage(dmabuf);
|
||||
|
||||
for (int i = 0; i < dmabuf.planeCount; ++i) {
|
||||
close(dmabuf.fd[i]);
|
||||
}
|
||||
|
||||
return image;
|
||||
return importDmaBufAsImage(dmaBufAttributesForBo(bo));
|
||||
}
|
||||
|
||||
std::shared_ptr<GLTexture> EglGbmBackend::importBufferObjectAsTexture(gbm_bo *bo)
|
||||
|
|
|
@ -26,7 +26,7 @@ inline DmaBufAttributes dmaBufAttributesForBo(gbm_bo *bo)
|
|||
|
||||
#if HAVE_GBM_BO_GET_FD_FOR_PLANE
|
||||
for (int i = 0; i < attributes.planeCount; ++i) {
|
||||
attributes.fd[i] = gbm_bo_get_fd_for_plane(bo, i);
|
||||
attributes.fd[i] = FileDescriptor{gbm_bo_get_fd_for_plane(bo, i)};
|
||||
attributes.offset[i] = gbm_bo_get_offset(bo, i);
|
||||
attributes.pitch[i] = gbm_bo_get_stride_for_plane(bo, i);
|
||||
}
|
||||
|
|
|
@ -1008,10 +1008,10 @@ std::shared_ptr<DmaBufTexture> WaylandBackend::createDmaBufTexture(const QSize &
|
|||
}
|
||||
|
||||
// The bo will be kept around until the last fd is closed.
|
||||
const DmaBufAttributes attributes = dmaBufAttributesForBo(bo);
|
||||
DmaBufAttributes attributes = dmaBufAttributesForBo(bo);
|
||||
gbm_bo_destroy(bo);
|
||||
m_eglBackend->makeCurrent();
|
||||
return std::make_shared<DmaBufTexture>(m_eglBackend->importDmaBufAsTexture(attributes), attributes);
|
||||
return std::make_shared<DmaBufTexture>(m_eglBackend->importDmaBufAsTexture(attributes), std::move(attributes));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "utils/filedescriptor.h"
|
||||
#include <cstdint>
|
||||
|
||||
namespace KWin
|
||||
|
@ -28,7 +29,7 @@ struct DmaBufAttributes
|
|||
uint32_t format = 0;
|
||||
uint64_t modifier = 0;
|
||||
|
||||
int fd[4] = {-1, -1, -1, -1};
|
||||
FileDescriptor fd[4];
|
||||
int offset[4] = {0, 0, 0, 0};
|
||||
int pitch[4] = {0, 0, 0, 0};
|
||||
};
|
||||
|
|
|
@ -13,21 +13,15 @@
|
|||
namespace KWin
|
||||
{
|
||||
|
||||
DmaBufTexture::DmaBufTexture(std::shared_ptr<GLTexture> texture, const DmaBufAttributes &attributes)
|
||||
DmaBufTexture::DmaBufTexture(std::shared_ptr<GLTexture> texture, DmaBufAttributes &&attributes)
|
||||
: m_texture(texture)
|
||||
, m_framebuffer(std::make_unique<GLFramebuffer>(texture.get()))
|
||||
, m_attributes(attributes)
|
||||
, m_attributes(std::move(attributes))
|
||||
{
|
||||
}
|
||||
DmaBufTexture::~DmaBufTexture() = default;
|
||||
|
||||
DmaBufTexture::~DmaBufTexture()
|
||||
{
|
||||
for (int i = 0; i < m_attributes.planeCount; ++i) {
|
||||
::close(m_attributes.fd[i]);
|
||||
}
|
||||
}
|
||||
|
||||
DmaBufAttributes DmaBufTexture::attributes() const
|
||||
const DmaBufAttributes &DmaBufTexture::attributes() const
|
||||
{
|
||||
return m_attributes;
|
||||
}
|
||||
|
|
|
@ -20,10 +20,10 @@ class GLTexture;
|
|||
class KWIN_EXPORT DmaBufTexture
|
||||
{
|
||||
public:
|
||||
explicit DmaBufTexture(std::shared_ptr<GLTexture> texture, const DmaBufAttributes &attributes);
|
||||
explicit DmaBufTexture(std::shared_ptr<GLTexture> texture, DmaBufAttributes &&attributes);
|
||||
virtual ~DmaBufTexture();
|
||||
|
||||
DmaBufAttributes attributes() const;
|
||||
const DmaBufAttributes &attributes() const;
|
||||
GLTexture *texture() const;
|
||||
GLFramebuffer *framebuffer() const;
|
||||
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
namespace KWin
|
||||
{
|
||||
|
||||
LinuxDmaBufV1ClientBuffer::LinuxDmaBufV1ClientBuffer(const DmaBufAttributes &attrs, quint32 flags)
|
||||
: KWaylandServer::LinuxDmaBufV1ClientBuffer(attrs, flags)
|
||||
LinuxDmaBufV1ClientBuffer::LinuxDmaBufV1ClientBuffer(DmaBufAttributes &&attrs, quint32 flags)
|
||||
: KWaylandServer::LinuxDmaBufV1ClientBuffer(std::move(attrs), flags)
|
||||
{
|
||||
waylandServer()->addLinuxDmabufBuffer(this);
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ LinuxDmaBufV1RendererInterface::~LinuxDmaBufV1RendererInterface()
|
|||
waylandServer()->linuxDmabuf()->setRendererInterface(nullptr);
|
||||
}
|
||||
|
||||
KWaylandServer::LinuxDmaBufV1ClientBuffer *LinuxDmaBufV1RendererInterface::importBuffer(const DmaBufAttributes &attrs, quint32 flags)
|
||||
KWaylandServer::LinuxDmaBufV1ClientBuffer *LinuxDmaBufV1RendererInterface::importBuffer(DmaBufAttributes &&attrs, quint32 flags)
|
||||
{
|
||||
Q_UNUSED(attrs)
|
||||
Q_UNUSED(flags)
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace KWin
|
|||
class KWIN_EXPORT LinuxDmaBufV1ClientBuffer : public KWaylandServer::LinuxDmaBufV1ClientBuffer
|
||||
{
|
||||
public:
|
||||
LinuxDmaBufV1ClientBuffer(const DmaBufAttributes &attrs, quint32 flags);
|
||||
LinuxDmaBufV1ClientBuffer(DmaBufAttributes &&attrs, quint32 flags);
|
||||
~LinuxDmaBufV1ClientBuffer() override;
|
||||
};
|
||||
|
||||
|
@ -28,7 +28,7 @@ public:
|
|||
explicit LinuxDmaBufV1RendererInterface();
|
||||
~LinuxDmaBufV1RendererInterface() override;
|
||||
|
||||
KWaylandServer::LinuxDmaBufV1ClientBuffer *importBuffer(const DmaBufAttributes &attrs, quint32 flags) override;
|
||||
KWaylandServer::LinuxDmaBufV1ClientBuffer *importBuffer(DmaBufAttributes &&attrs, quint32 flags) override;
|
||||
|
||||
protected:
|
||||
void setSupportedFormatsAndModifiers(const QVector<KWaylandServer::LinuxDmaBufV1Feedback::Tranche> &tranches);
|
||||
|
|
|
@ -407,7 +407,7 @@ EGLImageKHR AbstractEglBackend::importDmaBufAsImage(const DmaBufAttributes &dmab
|
|||
<< EGL_LINUX_DRM_FOURCC_EXT << dmabuf.format;
|
||||
|
||||
attribs
|
||||
<< EGL_DMA_BUF_PLANE0_FD_EXT << dmabuf.fd[0]
|
||||
<< EGL_DMA_BUF_PLANE0_FD_EXT << dmabuf.fd[0].get()
|
||||
<< EGL_DMA_BUF_PLANE0_OFFSET_EXT << dmabuf.offset[0]
|
||||
<< EGL_DMA_BUF_PLANE0_PITCH_EXT << dmabuf.pitch[0];
|
||||
if (dmabuf.modifier != DRM_FORMAT_MOD_INVALID) {
|
||||
|
@ -418,7 +418,7 @@ EGLImageKHR AbstractEglBackend::importDmaBufAsImage(const DmaBufAttributes &dmab
|
|||
|
||||
if (dmabuf.planeCount > 1) {
|
||||
attribs
|
||||
<< EGL_DMA_BUF_PLANE1_FD_EXT << dmabuf.fd[1]
|
||||
<< EGL_DMA_BUF_PLANE1_FD_EXT << dmabuf.fd[1].get()
|
||||
<< EGL_DMA_BUF_PLANE1_OFFSET_EXT << dmabuf.offset[1]
|
||||
<< EGL_DMA_BUF_PLANE1_PITCH_EXT << dmabuf.pitch[1];
|
||||
if (dmabuf.modifier != DRM_FORMAT_MOD_INVALID) {
|
||||
|
@ -430,7 +430,7 @@ EGLImageKHR AbstractEglBackend::importDmaBufAsImage(const DmaBufAttributes &dmab
|
|||
|
||||
if (dmabuf.planeCount > 2) {
|
||||
attribs
|
||||
<< EGL_DMA_BUF_PLANE2_FD_EXT << dmabuf.fd[2]
|
||||
<< EGL_DMA_BUF_PLANE2_FD_EXT << dmabuf.fd[2].get()
|
||||
<< EGL_DMA_BUF_PLANE2_OFFSET_EXT << dmabuf.offset[2]
|
||||
<< EGL_DMA_BUF_PLANE2_PITCH_EXT << dmabuf.pitch[2];
|
||||
if (dmabuf.modifier != DRM_FORMAT_MOD_INVALID) {
|
||||
|
@ -442,7 +442,7 @@ EGLImageKHR AbstractEglBackend::importDmaBufAsImage(const DmaBufAttributes &dmab
|
|||
|
||||
if (dmabuf.planeCount > 3) {
|
||||
attribs
|
||||
<< EGL_DMA_BUF_PLANE3_FD_EXT << dmabuf.fd[3]
|
||||
<< EGL_DMA_BUF_PLANE3_FD_EXT << dmabuf.fd[3].get()
|
||||
<< EGL_DMA_BUF_PLANE3_OFFSET_EXT << dmabuf.offset[3]
|
||||
<< EGL_DMA_BUF_PLANE3_PITCH_EXT << dmabuf.pitch[3];
|
||||
if (dmabuf.modifier != DRM_FORMAT_MOD_INVALID) {
|
||||
|
|
|
@ -91,22 +91,23 @@ YuvFormat yuvFormats[] = {
|
|||
2}}}};
|
||||
|
||||
EglDmabufBuffer::EglDmabufBuffer(EGLImage image,
|
||||
const DmaBufAttributes &attrs,
|
||||
DmaBufAttributes &&attrs,
|
||||
quint32 flags,
|
||||
EglDmabuf *interfaceImpl)
|
||||
: EglDmabufBuffer(attrs, flags, interfaceImpl)
|
||||
: EglDmabufBuffer(QVector{image}, std::move(attrs), flags, interfaceImpl)
|
||||
{
|
||||
m_importType = ImportType::Direct;
|
||||
addImage(image);
|
||||
}
|
||||
|
||||
EglDmabufBuffer::EglDmabufBuffer(const DmaBufAttributes &attrs,
|
||||
EglDmabufBuffer::EglDmabufBuffer(const QVector<EGLImage> &images,
|
||||
DmaBufAttributes &&attrs,
|
||||
quint32 flags,
|
||||
EglDmabuf *interfaceImpl)
|
||||
: LinuxDmaBufV1ClientBuffer(attrs, flags)
|
||||
: LinuxDmaBufV1ClientBuffer(std::move(attrs), flags)
|
||||
, m_images(images)
|
||||
, m_interfaceImpl(interfaceImpl)
|
||||
, m_importType(ImportType::Conversion)
|
||||
{
|
||||
m_importType = ImportType::Conversion;
|
||||
}
|
||||
|
||||
EglDmabufBuffer::~EglDmabufBuffer()
|
||||
|
@ -119,9 +120,9 @@ void EglDmabufBuffer::setInterfaceImplementation(EglDmabuf *interfaceImpl)
|
|||
m_interfaceImpl = interfaceImpl;
|
||||
}
|
||||
|
||||
void EglDmabufBuffer::addImage(EGLImage image)
|
||||
void EglDmabufBuffer::setImages(const QVector<EGLImage> &images)
|
||||
{
|
||||
m_images << image;
|
||||
m_images = images;
|
||||
}
|
||||
|
||||
void EglDmabufBuffer::removeImages()
|
||||
|
@ -132,13 +133,13 @@ void EglDmabufBuffer::removeImages()
|
|||
m_images.clear();
|
||||
}
|
||||
|
||||
KWaylandServer::LinuxDmaBufV1ClientBuffer *EglDmabuf::importBuffer(const DmaBufAttributes &attrs, quint32 flags)
|
||||
KWaylandServer::LinuxDmaBufV1ClientBuffer *EglDmabuf::importBuffer(DmaBufAttributes &&attrs, quint32 flags)
|
||||
{
|
||||
Q_ASSERT(attrs.planeCount > 0);
|
||||
|
||||
// Try first to import as a single image
|
||||
if (auto *img = m_backend->importDmaBufAsImage(attrs)) {
|
||||
return new EglDmabufBuffer(img, attrs, flags, this);
|
||||
return new EglDmabufBuffer(img, std::move(attrs), flags, this);
|
||||
}
|
||||
|
||||
// TODO: to enable this we must be able to store multiple textures per window pixmap
|
||||
|
@ -149,7 +150,7 @@ KWaylandServer::LinuxDmaBufV1ClientBuffer *EglDmabuf::importBuffer(const DmaBufA
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
KWaylandServer::LinuxDmaBufV1ClientBuffer *EglDmabuf::yuvImport(const DmaBufAttributes &attrs, quint32 flags)
|
||||
KWaylandServer::LinuxDmaBufV1ClientBuffer *EglDmabuf::yuvImport(DmaBufAttributes &&attrs, quint32 flags)
|
||||
{
|
||||
YuvFormat yuvFormat;
|
||||
for (YuvFormat f : yuvFormats) {
|
||||
|
@ -165,29 +166,27 @@ KWaylandServer::LinuxDmaBufV1ClientBuffer *EglDmabuf::yuvImport(const DmaBufAttr
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
auto *buf = new EglDmabufBuffer(attrs, flags, this);
|
||||
|
||||
QVector<EGLImage> images;
|
||||
for (int i = 0; i < yuvFormat.outputPlanes; i++) {
|
||||
const int planeIndex = yuvFormat.planes[i].planeIndex;
|
||||
const DmaBufAttributes planeAttrs {
|
||||
const DmaBufAttributes planeAttrs{
|
||||
.planeCount = 1,
|
||||
.width = attrs.width / yuvFormat.planes[i].widthDivisor,
|
||||
.height = attrs.height / yuvFormat.planes[i].heightDivisor,
|
||||
.format = yuvFormat.planes[i].format,
|
||||
.modifier = attrs.modifier,
|
||||
.fd = {attrs.fd[planeIndex], -1, -1, -1},
|
||||
.fd = {attrs.fd[planeIndex].duplicate()},
|
||||
.offset = {attrs.offset[planeIndex], 0, 0, 0},
|
||||
.pitch = {attrs.pitch[planeIndex], 0, 0, 0},
|
||||
};
|
||||
auto *image = m_backend->importDmaBufAsImage(planeAttrs);
|
||||
if (!image) {
|
||||
delete buf;
|
||||
return nullptr;
|
||||
}
|
||||
buf->addImage(image);
|
||||
images.push_back(image);
|
||||
}
|
||||
// TODO: add buf import properties
|
||||
return buf;
|
||||
|
||||
return new EglDmabufBuffer(images, std::move(attrs), flags, this);
|
||||
}
|
||||
|
||||
EglDmabuf *EglDmabuf::factory(AbstractEglBackend *backend)
|
||||
|
@ -215,7 +214,7 @@ EglDmabuf::EglDmabuf(AbstractEglBackend *backend)
|
|||
for (auto *buffer : prevBuffersSet) {
|
||||
auto *buf = static_cast<EglDmabufBuffer *>(buffer);
|
||||
buf->setInterfaceImplementation(this);
|
||||
buf->addImage(m_backend->importDmaBufAsImage(buf->attributes()));
|
||||
buf->setImages({m_backend->importDmaBufAsImage(buf->attributes())});
|
||||
}
|
||||
setSupportedFormatsAndModifiers();
|
||||
}
|
||||
|
|
|
@ -28,18 +28,19 @@ public:
|
|||
};
|
||||
|
||||
EglDmabufBuffer(EGLImage image,
|
||||
const DmaBufAttributes &attrs,
|
||||
DmaBufAttributes &&attrs,
|
||||
quint32 flags,
|
||||
EglDmabuf *interfaceImpl);
|
||||
|
||||
EglDmabufBuffer(const DmaBufAttributes &attrs,
|
||||
EglDmabufBuffer(const QVector<EGLImage> &images,
|
||||
DmaBufAttributes &&attrs,
|
||||
quint32 flags,
|
||||
EglDmabuf *interfaceImpl);
|
||||
|
||||
~EglDmabufBuffer() override;
|
||||
|
||||
void setInterfaceImplementation(EglDmabuf *interfaceImpl);
|
||||
void addImage(EGLImage image);
|
||||
void setImages(const QVector<EGLImage> &images);
|
||||
void removeImages();
|
||||
|
||||
QVector<EGLImage> images() const
|
||||
|
@ -61,7 +62,7 @@ public:
|
|||
explicit EglDmabuf(AbstractEglBackend *backend);
|
||||
~EglDmabuf() override;
|
||||
|
||||
KWaylandServer::LinuxDmaBufV1ClientBuffer *importBuffer(const DmaBufAttributes &attrs, quint32 flags) override;
|
||||
KWaylandServer::LinuxDmaBufV1ClientBuffer *importBuffer(DmaBufAttributes &&attrs, quint32 flags) override;
|
||||
|
||||
QVector<KWaylandServer::LinuxDmaBufV1Feedback::Tranche> tranches() const
|
||||
{
|
||||
|
@ -69,7 +70,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
KWaylandServer::LinuxDmaBufV1ClientBuffer *yuvImport(const DmaBufAttributes &attrs, quint32 flags);
|
||||
KWaylandServer::LinuxDmaBufV1ClientBuffer *yuvImport(DmaBufAttributes &&attrs, quint32 flags);
|
||||
|
||||
void setSupportedFormatsAndModifiers();
|
||||
|
||||
|
|
|
@ -192,11 +192,11 @@ void ScreenCastStream::onStreamAddBuffer(void *data, pw_buffer *buffer)
|
|||
if (dmabuff) {
|
||||
spa_data->maxsize = dmabuff->attributes().pitch[0] * stream->m_resolution.height();
|
||||
|
||||
const DmaBufAttributes dmabufAttribs = dmabuff->attributes();
|
||||
const DmaBufAttributes &dmabufAttribs = dmabuff->attributes();
|
||||
Q_ASSERT(buffer->buffer->n_datas >= uint(dmabufAttribs.planeCount));
|
||||
for (int i = 0; i < dmabufAttribs.planeCount; ++i) {
|
||||
buffer->buffer->datas[i].type = SPA_DATA_DmaBuf;
|
||||
buffer->buffer->datas[i].fd = dmabufAttribs.fd[i];
|
||||
buffer->buffer->datas[i].fd = dmabufAttribs.fd[i].get();
|
||||
buffer->buffer->datas[i].data = nullptr;
|
||||
}
|
||||
stream->m_dmabufDataForPwBuffer.insert(buffer, dmabuff);
|
||||
|
@ -450,7 +450,7 @@ void ScreenCastStream::recordFrame(const QRegion &damagedRegion)
|
|||
auto &buf = m_dmabufDataForPwBuffer[buffer];
|
||||
Q_ASSERT(buf);
|
||||
|
||||
const DmaBufAttributes dmabufAttribs = buf->attributes();
|
||||
const DmaBufAttributes &dmabufAttribs = buf->attributes();
|
||||
Q_ASSERT(buffer->buffer->n_datas >= uint(dmabufAttribs.planeCount));
|
||||
for (int i = 0; i < dmabufAttribs.planeCount; ++i) {
|
||||
buffer->buffer->datas[i].chunk->stride = dmabufAttribs.pitch[i];
|
||||
|
|
|
@ -40,7 +40,7 @@ FileDescriptor::~FileDescriptor()
|
|||
}
|
||||
}
|
||||
|
||||
FileDescriptor::operator bool() const
|
||||
bool FileDescriptor::isValid() const
|
||||
{
|
||||
return m_fd != -1;
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ public:
|
|||
FileDescriptor &operator=(FileDescriptor &&);
|
||||
~FileDescriptor();
|
||||
|
||||
explicit operator bool() const;
|
||||
bool isValid() const;
|
||||
int get() const;
|
||||
FileDescriptor duplicate() const;
|
||||
|
||||
|
|
|
@ -90,15 +90,6 @@ LinuxDmaBufParamsV1::LinuxDmaBufParamsV1(LinuxDmaBufV1ClientBufferIntegration *i
|
|||
{
|
||||
}
|
||||
|
||||
LinuxDmaBufParamsV1::~LinuxDmaBufParamsV1()
|
||||
{
|
||||
for (int i = 0; i < m_attrs.planeCount; ++i) {
|
||||
if (m_attrs.fd[i] != -1) {
|
||||
close(m_attrs.fd[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LinuxDmaBufParamsV1::zwp_linux_buffer_params_v1_destroy_resource(Resource *resource)
|
||||
{
|
||||
Q_UNUSED(resource)
|
||||
|
@ -130,13 +121,12 @@ void LinuxDmaBufParamsV1::zwp_linux_buffer_params_v1_add(Resource *resource,
|
|||
return;
|
||||
}
|
||||
|
||||
if (Q_UNLIKELY(m_attrs.fd[plane_idx] != -1)) {
|
||||
if (Q_UNLIKELY(m_attrs.fd[plane_idx].isValid())) {
|
||||
wl_resource_post_error(resource->handle, error_plane_set, "the plane index %d was already set", plane_idx);
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
m_attrs.fd[plane_idx] = fd;
|
||||
m_attrs.fd[plane_idx] = KWin::FileDescriptor{fd};
|
||||
m_attrs.offset[plane_idx] = offset;
|
||||
m_attrs.pitch[plane_idx] = stride;
|
||||
m_attrs.modifier = (quint64(modifier_hi) << 32) | modifier_lo;
|
||||
|
@ -160,14 +150,12 @@ void LinuxDmaBufParamsV1::zwp_linux_buffer_params_v1_create(Resource *resource,
|
|||
m_attrs.height = height;
|
||||
m_attrs.format = format;
|
||||
|
||||
LinuxDmaBufV1ClientBuffer *clientBuffer = m_integration->rendererInterface()->importBuffer(m_attrs, flags);
|
||||
LinuxDmaBufV1ClientBuffer *clientBuffer = m_integration->rendererInterface()->importBuffer(std::move(m_attrs), flags);
|
||||
if (!clientBuffer) {
|
||||
send_failed(resource->handle);
|
||||
return;
|
||||
}
|
||||
|
||||
m_attrs = KWin::DmaBufAttributes{}; // the ownership of file descriptors has been moved to the buffer
|
||||
|
||||
wl_resource *bufferResource = wl_resource_create(resource->client(), &wl_buffer_interface, 1, 0);
|
||||
if (!bufferResource) {
|
||||
delete clientBuffer;
|
||||
|
@ -204,14 +192,12 @@ void LinuxDmaBufParamsV1::zwp_linux_buffer_params_v1_create_immed(Resource *reso
|
|||
m_attrs.height = height;
|
||||
m_attrs.format = format;
|
||||
|
||||
LinuxDmaBufV1ClientBuffer *clientBuffer = m_integration->rendererInterface()->importBuffer(m_attrs, flags);
|
||||
LinuxDmaBufV1ClientBuffer *clientBuffer = m_integration->rendererInterface()->importBuffer(std::move(m_attrs), flags);
|
||||
if (!clientBuffer) {
|
||||
wl_resource_post_error(resource->handle, error_invalid_wl_buffer, "importing the supplied dmabufs failed");
|
||||
return;
|
||||
}
|
||||
|
||||
m_attrs = KWin::DmaBufAttributes{}; // the ownership of file descriptors has been moved to the buffer
|
||||
|
||||
wl_resource *bufferResource = wl_resource_create(resource->client(), &wl_buffer_interface, 1, buffer_id);
|
||||
if (!bufferResource) {
|
||||
delete clientBuffer;
|
||||
|
@ -234,7 +220,7 @@ bool LinuxDmaBufParamsV1::test(Resource *resource, uint32_t width, uint32_t heig
|
|||
|
||||
// Check for holes in the dmabuf set (e.g. [0, 1, 3]).
|
||||
for (int i = 0; i < m_attrs.planeCount; ++i) {
|
||||
if (m_attrs.fd[i] == -1) {
|
||||
if (!m_attrs.fd[i].isValid()) {
|
||||
wl_resource_post_error(resource->handle, error_incomplete, "no dmabuf has been added for plane %d", i);
|
||||
return false;
|
||||
}
|
||||
|
@ -259,7 +245,7 @@ bool LinuxDmaBufParamsV1::test(Resource *resource, uint32_t width, uint32_t heig
|
|||
|
||||
// Don't report an error as it might be caused by the kernel not supporting
|
||||
// seeking on dmabuf.
|
||||
const off_t size = lseek(m_attrs.fd[i], 0, SEEK_END);
|
||||
const off_t size = lseek(m_attrs.fd[i].get(), 0, SEEK_END);
|
||||
if (size == -1) {
|
||||
continue;
|
||||
}
|
||||
|
@ -366,25 +352,16 @@ void LinuxDmaBufV1ClientBufferPrivate::buffer_destroy(Resource *resource)
|
|||
wl_resource_destroy(resource->handle);
|
||||
}
|
||||
|
||||
LinuxDmaBufV1ClientBuffer::LinuxDmaBufV1ClientBuffer(const KWin::DmaBufAttributes &attrs, quint32 flags)
|
||||
LinuxDmaBufV1ClientBuffer::LinuxDmaBufV1ClientBuffer(KWin::DmaBufAttributes &&attrs, quint32 flags)
|
||||
: ClientBuffer(*new LinuxDmaBufV1ClientBufferPrivate)
|
||||
{
|
||||
Q_D(LinuxDmaBufV1ClientBuffer);
|
||||
d->attrs = attrs;
|
||||
d->attrs = std::move(attrs);
|
||||
d->flags = flags;
|
||||
d->hasAlphaChannel = testAlphaChannel(attrs.format);
|
||||
}
|
||||
|
||||
LinuxDmaBufV1ClientBuffer::~LinuxDmaBufV1ClientBuffer()
|
||||
{
|
||||
Q_D(LinuxDmaBufV1ClientBuffer);
|
||||
for (int i = 0; i < d->attrs.planeCount; ++i) {
|
||||
if (d->attrs.fd[i] != -1) {
|
||||
close(d->attrs.fd[i]);
|
||||
d->attrs.fd[i] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
LinuxDmaBufV1ClientBuffer::~LinuxDmaBufV1ClientBuffer() = default;
|
||||
|
||||
void LinuxDmaBufV1ClientBuffer::initialize(wl_resource *resource)
|
||||
{
|
||||
|
@ -405,7 +382,7 @@ quint32 LinuxDmaBufV1ClientBuffer::flags() const
|
|||
return d->flags;
|
||||
}
|
||||
|
||||
KWin::DmaBufAttributes LinuxDmaBufV1ClientBuffer::attributes() const
|
||||
const KWin::DmaBufAttributes &LinuxDmaBufV1ClientBuffer::attributes() const
|
||||
{
|
||||
Q_D(const LinuxDmaBufV1ClientBuffer);
|
||||
return d->attrs;
|
||||
|
@ -463,7 +440,7 @@ LinuxDmaBufV1FeedbackPrivate::LinuxDmaBufV1FeedbackPrivate(LinuxDmaBufV1ClientBu
|
|||
|
||||
void LinuxDmaBufV1FeedbackPrivate::send(Resource *resource)
|
||||
{
|
||||
send_format_table(resource->handle, m_bufferintegration->table->fd, m_bufferintegration->table->size);
|
||||
send_format_table(resource->handle, m_bufferintegration->table->fd.get(), m_bufferintegration->table->size);
|
||||
QByteArray bytes;
|
||||
bytes.append(reinterpret_cast<const char *>(&m_bufferintegration->mainDevice), sizeof(dev_t));
|
||||
send_main_device(resource->handle, bytes);
|
||||
|
@ -529,8 +506,8 @@ LinuxDmaBufV1FormatTable::LinuxDmaBufV1FormatTable(const QHash<uint32_t, QVector
|
|||
qCWarning(KWIN_CORE) << "Failed to create keymap file:" << tmp->errorString();
|
||||
return;
|
||||
}
|
||||
fd = open(tmp->fileName().toUtf8().constData(), O_RDONLY | O_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
fd = KWin::FileDescriptor(open(tmp->fileName().toUtf8().constData(), O_RDONLY | O_CLOEXEC));
|
||||
if (!fd.isValid()) {
|
||||
qCWarning(KWIN_CORE) << "Could not create readonly shm fd!" << strerror(errno);
|
||||
return;
|
||||
}
|
||||
|
@ -547,11 +524,4 @@ LinuxDmaBufV1FormatTable::LinuxDmaBufV1FormatTable(const QHash<uint32_t, QVector
|
|||
memcpy(address, data.data(), size);
|
||||
}
|
||||
|
||||
LinuxDmaBufV1FormatTable::~LinuxDmaBufV1FormatTable()
|
||||
{
|
||||
if (fd != -1) {
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace KWaylandServer
|
||||
|
|
|
@ -35,12 +35,12 @@ class KWIN_EXPORT LinuxDmaBufV1ClientBuffer : public ClientBuffer
|
|||
Q_DECLARE_PRIVATE(LinuxDmaBufV1ClientBuffer)
|
||||
|
||||
public:
|
||||
LinuxDmaBufV1ClientBuffer(const KWin::DmaBufAttributes &attrs, quint32 flags);
|
||||
LinuxDmaBufV1ClientBuffer(KWin::DmaBufAttributes &&attrs, quint32 flags);
|
||||
~LinuxDmaBufV1ClientBuffer() override;
|
||||
|
||||
quint32 format() const;
|
||||
quint32 flags() const;
|
||||
KWin::DmaBufAttributes attributes() const;
|
||||
const KWin::DmaBufAttributes &attributes() const;
|
||||
|
||||
QSize size() const override;
|
||||
bool hasAlphaChannel() const override;
|
||||
|
@ -115,7 +115,7 @@ public:
|
|||
*
|
||||
* @return The imported buffer on success, and nullptr otherwise.
|
||||
*/
|
||||
virtual LinuxDmaBufV1ClientBuffer *importBuffer(const KWin::DmaBufAttributes &attrs, quint32 flags) = 0;
|
||||
virtual LinuxDmaBufV1ClientBuffer *importBuffer(KWin::DmaBufAttributes &&attrs, quint32 flags) = 0;
|
||||
};
|
||||
|
||||
RendererInterface *rendererInterface() const;
|
||||
|
|
|
@ -62,7 +62,6 @@ class LinuxDmaBufParamsV1 : public QtWaylandServer::zwp_linux_buffer_params_v1
|
|||
{
|
||||
public:
|
||||
LinuxDmaBufParamsV1(LinuxDmaBufV1ClientBufferIntegration *integration, ::wl_resource *resource);
|
||||
~LinuxDmaBufParamsV1() override;
|
||||
|
||||
protected:
|
||||
void zwp_linux_buffer_params_v1_destroy_resource(Resource *resource) override;
|
||||
|
@ -90,9 +89,8 @@ class LinuxDmaBufV1FormatTable
|
|||
{
|
||||
public:
|
||||
LinuxDmaBufV1FormatTable(const QHash<uint32_t, QVector<uint64_t>> &supportedModifiers);
|
||||
~LinuxDmaBufV1FormatTable();
|
||||
|
||||
int fd = -1;
|
||||
KWin::FileDescriptor fd;
|
||||
int size;
|
||||
QMap<std::pair<uint32_t, uint64_t>, uint16_t> indices;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue