Untangle SurfaceInterface and BufferInterface

A wl_buffer object can be bound to multiple surfaces or none at all. So
the BufferInterface::surface() property makes very little sense.
This commit is contained in:
Vlad Zahorodnii 2020-09-21 14:31:08 +03:00
parent 0b3cca4ae0
commit e727dc2fa9
5 changed files with 28 additions and 34 deletions

View file

@ -7,7 +7,6 @@
#include "compositor_interface.h"
#include "display.h"
#include "logging.h"
#include "surface_interface.h"
#include "linuxdmabuf_v1_interface.h"
// Wayland
#include <wayland-server.h>
@ -29,14 +28,13 @@ eglQueryWaylandBufferWL_func eglQueryWaylandBufferWL = nullptr;
class BufferInterface::Private
{
public:
Private(BufferInterface *q, wl_resource *resource, SurfaceInterface *parent);
Private(BufferInterface *q, Display *display, wl_resource *resource);
~Private();
QImage::Format format() const;
QImage createImage();
wl_resource *buffer;
wl_shm_buffer *shmBuffer;
LinuxDmabufBuffer *dmabufBuffer;
SurfaceInterface *surface;
int refCount;
QSize size;
bool alpha;
@ -89,11 +87,10 @@ void BufferInterface::Private::imageBufferCleanupHandler(void *info)
wl_shm_buffer_end_access(p->shmBuffer);
}
BufferInterface::Private::Private(BufferInterface *q, wl_resource *resource, SurfaceInterface *parent)
BufferInterface::Private::Private(BufferInterface *q, Display *display, wl_resource *resource)
: buffer(resource)
, shmBuffer(wl_shm_buffer_get(resource))
, dmabufBuffer(nullptr)
, surface(parent)
, refCount(0)
, alpha(false)
, q(q)
@ -155,8 +152,8 @@ BufferInterface::Private::Private(BufferInterface *q, wl_resource *resource, Sur
break;
}
size = dmabufBuffer->size();
} else if (parent) {
EGLDisplay eglDisplay = parent->compositor()->display()->eglDisplay();
} else {
EGLDisplay eglDisplay = display->eglDisplay();
static bool resolved = false;
using namespace EGL;
if (!resolved && eglDisplay != EGL_NO_DISPLAY) {
@ -194,7 +191,7 @@ BufferInterface::Private::~Private()
s_buffers.removeAll(this);
}
BufferInterface *BufferInterface::get(wl_resource *r)
BufferInterface *BufferInterface::get(Display *display, wl_resource *r)
{
if (!r) {
return nullptr;
@ -204,12 +201,12 @@ BufferInterface *BufferInterface::get(wl_resource *r)
if (b) {
return b;
}
return new BufferInterface(r, nullptr);
return new BufferInterface(display, r);
}
BufferInterface::BufferInterface(wl_resource *resource, SurfaceInterface *parent)
BufferInterface::BufferInterface(Display *display, wl_resource *resource)
: QObject()
, d(new Private(this, resource, parent))
, d(new Private(this, display, resource))
{
}
@ -295,11 +292,6 @@ bool BufferInterface::isReferenced() const
return d->refCount > 0;
}
SurfaceInterface *BufferInterface::surface() const
{
return d->surface;
}
wl_shm_buffer *BufferInterface::shmBuffer()
{
return d->shmBuffer;

View file

@ -16,7 +16,7 @@ struct wl_shm_buffer;
namespace KWaylandServer
{
class SurfaceInterface;
class Display;
class LinuxDmabufBuffer;
/**
@ -51,7 +51,7 @@ class KWAYLANDSERVER_EXPORT BufferInterface : public QObject
Q_OBJECT
public:
explicit BufferInterface(wl_resource *resource, SurfaceInterface *parent);
BufferInterface(Display *display, wl_resource *resource);
virtual ~BufferInterface();
/**
* Reference the BufferInterface.
@ -67,8 +67,7 @@ public:
* Unreference the BufferInterface.
*
* If the reference counting reached @c 0 the BufferInterface is released, so that the
* client can use it again. The instance of this BufferInterface will be automatically
* deleted.
* client can use it again.
*
* @see ref
* @see isReferenced
@ -82,10 +81,6 @@ public:
**/
bool isReferenced() const;
/**
* @returns The SurfaceInterface this BufferInterface is attached to.
**/
SurfaceInterface *surface() const;
/**
* @returns The native wl_shm_buffer if the BufferInterface represents a shared memory buffer, otherwise @c nullptr.
**/
@ -162,7 +157,7 @@ public:
**/
bool hasAlphaChannel() const;
static BufferInterface *get(wl_resource *r);
static BufferInterface *get(Display *display, wl_resource *r);
Q_SIGNALS:
void aboutToBeDestroyed(KWaylandServer::BufferInterface*);

View file

@ -19,6 +19,7 @@ public:
ShadowManagerInterfacePrivate(ShadowManagerInterface *_q, Display *display);
ShadowManagerInterface *q;
Display *display;
static const quint32 s_version;
protected:
@ -32,6 +33,7 @@ const quint32 ShadowManagerInterfacePrivate::s_version = 2;
ShadowManagerInterfacePrivate::ShadowManagerInterfacePrivate(ShadowManagerInterface *_q, Display *display)
: QtWaylandServer::org_kde_kwin_shadow_manager(*display, s_version)
, q(_q)
, display(display)
{
}
@ -54,7 +56,7 @@ void ShadowManagerInterfacePrivate::org_kde_kwin_shadow_manager_create(Resource
return;
}
auto shadow = new ShadowInterface(shadow_resource);
auto shadow = new ShadowInterface(q, shadow_resource);
SurfaceInterfacePrivate *surfacePrivate = SurfaceInterfacePrivate::get(s);
surfacePrivate->setShadow(QPointer<ShadowInterface>(shadow));
@ -80,6 +82,11 @@ ShadowManagerInterface::ShadowManagerInterface(Display *display, QObject *parent
ShadowManagerInterface::~ShadowManagerInterface() = default;
Display *ShadowManagerInterface::display() const
{
return d->display;
}
class ShadowInterfacePrivate : public QtWaylandServer::org_kde_kwin_shadow
{
public:
@ -114,6 +121,7 @@ public:
void commit();
void attach(State::Flags flag, wl_resource *buffer);
ShadowManagerInterface *manager;
State current;
State pending;
ShadowInterface *q;
@ -168,7 +176,7 @@ void ShadowInterfacePrivate::org_kde_kwin_shadow_commit(Resource *resource)
void ShadowInterfacePrivate::attach(ShadowInterfacePrivate::State::Flags flag, wl_resource *buffer)
{
BufferInterface *b = BufferInterface::get(buffer);
BufferInterface *b = BufferInterface::get(manager->display(), buffer);
if (b) {
QObject::connect(b, &BufferInterface::aboutToBeDestroyed, q,
[this](BufferInterface *buffer) {
@ -345,10 +353,11 @@ ShadowInterfacePrivate::~ShadowInterfacePrivate()
#undef CURRENT
}
ShadowInterface::ShadowInterface(wl_resource *resource)
ShadowInterface::ShadowInterface(ShadowManagerInterface *manager, wl_resource *resource)
: QObject()
, d(new ShadowInterfacePrivate(this, resource))
{
d->manager = manager;
}
ShadowInterface::~ShadowInterface() = default;

View file

@ -27,6 +27,8 @@ class KWAYLANDSERVER_EXPORT ShadowManagerInterface : public QObject
public:
~ShadowManagerInterface() override;
Display *display() const;
private:
explicit ShadowManagerInterface(Display *display, QObject *parent = nullptr);
friend class Display;
@ -51,7 +53,7 @@ public:
QMarginsF offset() const;
private:
explicit ShadowInterface(wl_resource *resource);
explicit ShadowInterface(ShadowManagerInterface *manager, wl_resource *resource);
friend class ShadowManagerInterfacePrivate;
QScopedPointer<ShadowInterfacePrivate> d;

View file

@ -298,9 +298,6 @@ void SurfaceInterfacePrivate::surface_attach(Resource *resource, struct ::wl_res
Q_UNUSED(resource)
pending.bufferIsSet = true;
pending.offset = QPoint(x, y);
if (pending.buffer) {
delete pending.buffer;
}
if (!buffer) {
// got a null buffer, deletes content in next frame
pending.buffer = nullptr;
@ -308,7 +305,7 @@ void SurfaceInterfacePrivate::surface_attach(Resource *resource, struct ::wl_res
pending.bufferDamage = QRegion();
return;
}
pending.buffer = new BufferInterface(buffer, q);
pending.buffer = BufferInterface::get(compositor->display(), buffer);
QObject::connect(pending.buffer, &BufferInterface::aboutToBeDestroyed, q,
[this](BufferInterface *buffer) {
if (pending.buffer == buffer) {
@ -524,7 +521,6 @@ void SurfaceInterfacePrivate::swapStates(State *source, State *target, bool emit
if (emitChanged) {
target->buffer->unref();
} else {
delete target->buffer;
target->buffer = nullptr;
}
}