kwin/src/core/graphicsbuffer.h
Vlad Zahorodnii 380aaab2cc Fix deleting GraphicsBuffer twice
When GraphicsBuffer::dropped() is emitted, the buffer can be
unreferenced. If that's the case, the GraphicsBuffer will be deleted
twice: first in GraphicsBuffer::unref(), the second time in drop().

In order to address the issue, this change gets rid of the
GraphicsBuffer::dropped() signal, so it's always guaranteed that the
buffer stays alive until the reference count is checked.

The GraphicsBuffer::dropped() signal is used to remove the mapping
between wl_resource and ShmClientBuffer when the corresponding
wl_shm_buffer object is destroyed. On the other hand, we could perform
such cleanup when calling drop() too. This code can be further improved
by reimplementing wl-shm, which we need to do at some point in the
future.
2023-05-09 16:29:00 +00:00

77 lines
1.5 KiB
C++

/*
SPDX-FileCopyrightText: 2023 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include "kwin_export.h"
#include "utils/filedescriptor.h"
#include <QObject>
#include <QSize>
namespace KWin
{
struct DmaBufAttributes
{
int planeCount = 0;
int width = 0;
int height = 0;
uint32_t format = 0;
uint64_t modifier = 0;
FileDescriptor fd[4];
int offset[4] = {0, 0, 0, 0};
int pitch[4] = {0, 0, 0, 0};
};
struct ShmAttributes
{
FileDescriptor fd;
int stride;
off_t offset;
QSize size;
uint32_t format;
};
/**
* The GraphicsBuffer class represents a chunk of memory containing graphics data.
*
* A graphics buffer can be referenced. In which case, it won't be destroyed until all
* references are dropped. You can use the isDropped() function to check whether the
* buffer has been marked as destroyed.
*/
class KWIN_EXPORT GraphicsBuffer : public QObject
{
Q_OBJECT
public:
explicit GraphicsBuffer(QObject *parent = nullptr);
bool isReferenced() const;
bool isDropped() const;
void ref();
void unref();
void drop();
virtual QSize size() const = 0;
virtual bool hasAlphaChannel() const = 0;
virtual const DmaBufAttributes *dmabufAttributes() const;
virtual const ShmAttributes *shmAttributes() const;
static bool alphaChannelFromDrmFormat(uint32_t format);
Q_SIGNALS:
void released();
protected:
int m_refCount = 0;
bool m_dropped = false;
};
} // namespace KWin